Java 有没有办法在JScrollPane上显示2D图形
我有一段代码,可以创建一个频率表条形图Java 有没有办法在JScrollPane上显示2D图形,java,swing,graphics,jpanel,jscrollpane,Java,Swing,Graphics,Jpanel,Jscrollpane,我有一段代码,可以创建一个频率表条形图ChartPanel(String chartTitle,ArrayList chartValues,ArrayList chartValuesFrequency) 代码当前将所有数据显示在当前视口大小上。我尝试将条形图的宽度设置为300,但是条形图会从面板上消失。然后我决定将其添加到JScrollPane中,并将首选大小设置为3000左右的宽度。然而,这是非常低效的,因为图表值的数量可能会改变 import javax.swing.*; import ja
ChartPanel(String chartTitle,ArrayList chartValues,ArrayList chartValuesFrequency)
代码当前将所有数据显示在当前视口大小上。我尝试将条形图的宽度设置为300,但是条形图会从面板上消失。然后我决定将其添加到JScrollPane中,并将首选大小设置为3000左右的宽度。然而,这是非常低效的,因为图表值的数量可能会改变
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
public class ChartPanel extends JPanel {
private final String title;
private final ArrayList<String> values;
private final ArrayList<Integer> frequency;
private int clientWidth;
public ChartPanel(String chartTitle, ArrayList<String> chartValues, ArrayList<Integer> chartValuesFrequency) {
this.title = chartTitle;
this.values = chartValues;
this.frequency = chartValuesFrequency;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (frequency == null || frequency.size() == 0)
return;
int minValue = 0;
int maxValue = 0;
for (Integer integer : frequency) {
if (minValue > integer)
minValue = integer;
if (maxValue < integer)
maxValue = integer;
}
Dimension d = getSize();
clientWidth = d.width;
int clientHeight = d.height;
int barWidth = 300;
Font titleFont = new Font("SansSerif", Font.BOLD, 20);
FontMetrics titleFontMetrics = g.getFontMetrics(titleFont);
Font labelFont = new Font("SansSerif", Font.PLAIN, 10);
FontMetrics labelFontMetrics = g.getFontMetrics(labelFont);
int titleWidth = titleFontMetrics.stringWidth(title);
int y = titleFontMetrics.getAscent();
int x = (clientWidth - titleWidth) / 2;
g.setFont(titleFont);
g.drawString(title, x, y);
int top = titleFontMetrics.getHeight();
int bottom = labelFontMetrics.getHeight();
if (maxValue == minValue)
return;
int scale = (clientHeight - top - bottom) / (maxValue - minValue);
y = clientHeight - labelFontMetrics.getDescent();
g.setFont(labelFont);
for (int i = 0; i < frequency.size(); i++) {
int valueX = i * barWidth + 1;
int valueY = top;
int height = frequency.get(i)* scale;
if (frequency.get(i) >= 0)
valueY += (maxValue - frequency.get(i)) * scale;
else {
valueY += maxValue * scale;
height = -height;
}
g.setColor(Color.LIGHT_GRAY);
g.fillRect(valueX, valueY, barWidth - 2, height);
g.setColor(Color.black);
g.drawRect(valueX, valueY, barWidth - 2, height);
String label = values.get(i);
if (label.equals("")){
int labelWidth = labelFontMetrics.stringWidth(values.get(i));
x = i * barWidth + (barWidth - labelWidth) / 2;
g.drawString("Null Value", x, y);
}else{
int labelWidth = labelFontMetrics.stringWidth(values.get(i));
x = i * barWidth + (barWidth - labelWidth) / 2;
g.drawString(values.get(i), x, y);
}
}
}
}
import javax.swing.*;
导入java.awt.*;
导入java.util.ArrayList;
公共类ChartPanel扩展了JPanel{
私人最终字符串标题;
私有最终ArrayList值;
专用最终阵列列表频率;
私有int客户端宽度;
公共图表面板(字符串图表标题、ArrayList图表值、ArrayList图表值频率){
this.title=图表标题;
this.values=图表值;
this.frequency=图表值频率;
}
公共组件(图形g){
超级组件(g);
if(frequency==null | | frequency.size()==0)
返回;
int minValue=0;
int maxValue=0;
用于(整数:频率){
如果(最小值>整数)
最小值=整数;
如果(最大值<整数)
最大值=整数;
}
维度d=getSize();
clientWidth=d.width;
int clientHeight=d.高度;
int barWidth=300;
字体标题字体=新字体(“SansSerif”,Font.BOLD,20);
FontMetrics titleFontMetrics=g.getFontMetrics(titleFont);
Font labelFont=新字体(“SansSerif”,Font.PLAIN,10);
FontMetrics-labelFontMetrics=g.getFontMetrics(labelFont);
int titleWidth=titleFontMetrics.stringWidth(标题);
int y=titleFontMetrics.getAscent();
intx=(clientWidth-titleWidth)/2;
g、 setFont(标题字体);
g、 抽绳(标题,x,y);
int top=titleFontMetrics.getHeight();
int bottom=labelFontMetrics.getHeight();
如果(maxValue==minValue)
返回;
int scale=(clientHeight-上-下)/(maxValue-minValue);
y=clientHeight-labelFontMetrics.getDescent();
g、 setFont(labelFont);
对于(int i=0;i=0)
valueY+=(maxValue-frequency.get(i))*刻度;
否则{
valueY+=最大值*刻度;
高度=-高度;
}
g、 setColor(颜色:浅灰色);
g、 fillRect(valueX、valueY、条形宽度-2、高度);
g、 设置颜色(颜色为黑色);
g、 drawRect(valueX、valueY、杆宽-2、高度);
字符串标签=value.get(i);
if(标签号等于(“”){
int-labelWidth=labelFontMetrics.stringWidth(values.get(i));
x=i*barWidth+(barWidth-labelWidth)/2;
g、 抽绳(“空值”,x,y);
}否则{
int-labelWidth=labelFontMetrics.stringWidth(values.get(i));
x=i*barWidth+(barWidth-labelWidth)/2;
g、 抽绳(值。get(i),x,y);
}
}
}
}
非常感谢您的帮助。每个Swing组件都负责确定自己的首选尺寸。在进行自定义绘制时,需要重写类的getPreferredSize()方法。当面板的首选大小大于滚动面板的大小时,滚动条将出现在JScrollPane中。这显示了一种方式。