在 JPanel 上绘制条形图并将其添加到 JScrollPane 上适用于 Mac OS 但不适用于 Windows OS?
Drawing Bar Chart on JPanel and adding it onto a JScrollPane works on Mac OS but not on Windows OS?
我的代码的一个特点是它显示一个频率条形图,其中包含给定的数据。在我的 Mac 书中,它工作得很好,但是当我尝试在我的 Razer Blade 灵刃上使用它时,它没有按预期工作。我提供了屏幕截图,这样你就可以看到发生了什么,如果你能给我一些关于这方面的见解。
WindowsOS:
https://gyazo.com/5107eed39d548687ad772a60e065055b
MacOS:
https://gyazo.com/6d32df9e08b9ce0c089dbe1b4d35af64
import javax.swing.*;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args){
SwingUtilities.invokeLater(BarChartGUI::new);
}
}
class BarChartGUI extends JFrame{
public BarChartGUI(){
Map<String, Integer> frequencyTableData = getFrequencyTableData();
BarChart barChart = new BarChart(frequencyTableData);
JScrollPane chartScrollPane = new JScrollPane(barChart);
chartScrollPane.setPreferredSize(new Dimension(1000, 500));
add(chartScrollPane);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
private Map<String, Integer> getFrequencyTableData(){
Map<String, Integer> frequencyTableData = new HashMap<>();
for (int i = 0; i < 2000; i++){
frequencyTableData.put(String.valueOf(i), i);
}
return frequencyTableData;
}
}
class BarChart extends JPanel {
// Space to draw Chart Information
public static final int TOP_BUFFER = 30;
public static final int AXIS_OFFSET = 20;
// Hashmap datatype holds the frequency of the String within the columnValues
private final Map<String, Integer> data;
// Stores dimension values
private int chartWidth;
private int chartHeight;
private int chartY;
public BarChart(Map<String, Integer> frequencyTableData){
super();
data = frequencyTableData;
setBackground(Color.white);
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
computeSize();
drawBars(g2);
}
// Retrieves the size of panel
private void computeSize() {
// Gets the chart's area size
chartWidth = this.getWidth() - 2*AXIS_OFFSET;
chartHeight = this.getHeight() - 2*AXIS_OFFSET - TOP_BUFFER;
// Get's the chart's coords for the origin
chartY = this.getHeight() - AXIS_OFFSET;
}
// Draws the Bar Chart depending on the values and its frequency stored within data
public void drawBars(Graphics2D g2) {
int numberOfBars = data.size();
double maxHeight = 0;
// Finds the height of the highest bar
for (Integer freq : data.values()) {
if (maxHeight < freq)
maxHeight = freq;
}
// Calculates width of bar
int barWidth = chartWidth / numberOfBars;
if ((chartWidth / numberOfBars) < 5){
barWidth = 5;
}
int value;
int barHeight;
int xLeftCord;
int yTopLeftCord;
int counter = 0;
g2.setColor(Color.black);
// Draws the bar for every key in the hashmap
for (String bar : data.keySet()) {
value = data.get(bar);
double barHeightDecimal = (value/maxHeight)* chartHeight;
barHeight = (int) barHeightDecimal;
xLeftCord = AXIS_OFFSET + counter * barWidth;
yTopLeftCord = chartY - barHeight;
Rectangle rec = new Rectangle(xLeftCord, yTopLeftCord, barWidth, barHeight);
g2.draw(rec);
counter++;
}
}
}
这个:
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
computeSize();
drawBars(g2);
}
缺少对超级方法的调用:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
computeSize();
drawBars(g2);
}
没有这个,JPanel 将无法进行内务处理绘画或清除脏像素
我的代码的一个特点是它显示一个频率条形图,其中包含给定的数据。在我的 Mac 书中,它工作得很好,但是当我尝试在我的 Razer Blade 灵刃上使用它时,它没有按预期工作。我提供了屏幕截图,这样你就可以看到发生了什么,如果你能给我一些关于这方面的见解。
WindowsOS: https://gyazo.com/5107eed39d548687ad772a60e065055b
MacOS: https://gyazo.com/6d32df9e08b9ce0c089dbe1b4d35af64
import javax.swing.*;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args){
SwingUtilities.invokeLater(BarChartGUI::new);
}
}
class BarChartGUI extends JFrame{
public BarChartGUI(){
Map<String, Integer> frequencyTableData = getFrequencyTableData();
BarChart barChart = new BarChart(frequencyTableData);
JScrollPane chartScrollPane = new JScrollPane(barChart);
chartScrollPane.setPreferredSize(new Dimension(1000, 500));
add(chartScrollPane);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
private Map<String, Integer> getFrequencyTableData(){
Map<String, Integer> frequencyTableData = new HashMap<>();
for (int i = 0; i < 2000; i++){
frequencyTableData.put(String.valueOf(i), i);
}
return frequencyTableData;
}
}
class BarChart extends JPanel {
// Space to draw Chart Information
public static final int TOP_BUFFER = 30;
public static final int AXIS_OFFSET = 20;
// Hashmap datatype holds the frequency of the String within the columnValues
private final Map<String, Integer> data;
// Stores dimension values
private int chartWidth;
private int chartHeight;
private int chartY;
public BarChart(Map<String, Integer> frequencyTableData){
super();
data = frequencyTableData;
setBackground(Color.white);
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
computeSize();
drawBars(g2);
}
// Retrieves the size of panel
private void computeSize() {
// Gets the chart's area size
chartWidth = this.getWidth() - 2*AXIS_OFFSET;
chartHeight = this.getHeight() - 2*AXIS_OFFSET - TOP_BUFFER;
// Get's the chart's coords for the origin
chartY = this.getHeight() - AXIS_OFFSET;
}
// Draws the Bar Chart depending on the values and its frequency stored within data
public void drawBars(Graphics2D g2) {
int numberOfBars = data.size();
double maxHeight = 0;
// Finds the height of the highest bar
for (Integer freq : data.values()) {
if (maxHeight < freq)
maxHeight = freq;
}
// Calculates width of bar
int barWidth = chartWidth / numberOfBars;
if ((chartWidth / numberOfBars) < 5){
barWidth = 5;
}
int value;
int barHeight;
int xLeftCord;
int yTopLeftCord;
int counter = 0;
g2.setColor(Color.black);
// Draws the bar for every key in the hashmap
for (String bar : data.keySet()) {
value = data.get(bar);
double barHeightDecimal = (value/maxHeight)* chartHeight;
barHeight = (int) barHeightDecimal;
xLeftCord = AXIS_OFFSET + counter * barWidth;
yTopLeftCord = chartY - barHeight;
Rectangle rec = new Rectangle(xLeftCord, yTopLeftCord, barWidth, barHeight);
g2.draw(rec);
counter++;
}
}
}
这个:
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
computeSize();
drawBars(g2);
}
缺少对超级方法的调用:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
computeSize();
drawBars(g2);
}
没有这个,JPanel 将无法进行内务处理绘画或清除脏像素