在调整 ChartPanel 大小时重新计算 JFreeChart 显示
Recompute JFreeChart display on ChartPanel resize
我在 ChartPanel
中嵌入了一张图表。首次渲染面板时,一切看起来都不错:
但是当尺寸改变时,面板内容被拉伸,使文本更难阅读:
这就像 JFreeChart 正在预渲染显示,因此它可以快速在屏幕上绘制它,这对于例如PNG 导出(我知道这是 JFreeChart 作者 David Gilbert 想要保留的一个功能),但是当购物车尺寸变化太大时,显示效果不佳。
有没有办法告诉 JFreeChart 在容器调整大小时以某种方式重新呈现图表?
这是 SSCCE:
public static void main(String[] args) {
JFrame frm = new JFrame("JFreeChart resizing");
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CategoryDataset ds = new DefaultCategoryDataset();
JFreeChart chart = ChartFactory.createLineChart("Title", "X axis", "Y axis", ds);
ChartPanel cp = new ChartPanel(chart);
frm.getContentPane().add(cp, BorderLayout.CENTER);
frm.pack();
frm.setVisible(true);
}
Solving Common Layout Problems 建议,“确保您的组件的容器使用尊重组件请求大小的布局管理器。”您的片段使用 BorderLayout.CENTER
,这是一个不错的选择:它允许 ChartPanel
在调整框架大小时平滑地调整大小,但它会忽略面板的最小尺寸。最终,出现重采样伪像和失真。当您想保留调整大小行为时,一种方法是将图表面板的最小绘制宽度和高度设置为零,并(可选)相应地限制框架的最小尺寸:
cp.setMinimumDrawWidth(0);
cp.setMinimumDrawHeight(0);
// optionally
f.setMinimumSize(new Dimension(
cp.getMinimumDrawWidth(),
cp.getMinimumDrawHeight()));
绘图宽度和高度也可以在构造函数中指定,如 here 所示。在下面的例子中,注意:
覆盖 getPreferredSize()
to establish the initial preferred size, also discussed here。
- 上 仅 构造和操作 Swing GUI 对象
首选尺码:
较小的尺寸:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
/**
* @see
*/
public class ChartTest {
private static final int W = 320;
private static final int H = 240;
private void display() {
JFrame f = new JFrame("JFreeChart Resizing");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CategoryDataset ds = new DefaultCategoryDataset();
JFreeChart chart = ChartFactory.createLineChart(
"Chart Title", "X axis", "Y axis", ds);
ChartPanel cp = new ChartPanel(chart) {
@Override
public Dimension getPreferredSize() {
return new Dimension(W, H);
}
};
f.add(cp, BorderLayout.CENTER);
f.add(new JLabel("Java v" + System.getProperty("java.version")
+ "; JFreeChart 1.5.3", JLabel.CENTER), BorderLayout.PAGE_END);
cp.setMinimumDrawWidth(0);
cp.setMinimumDrawHeight(0);
f.setMinimumSize(new Dimension(cp.getMinimumDrawWidth(), cp.getMinimumDrawHeight()));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new ChartTest()::display);
}
}
我在 ChartPanel
中嵌入了一张图表。首次渲染面板时,一切看起来都不错:
但是当尺寸改变时,面板内容被拉伸,使文本更难阅读:
这就像 JFreeChart 正在预渲染显示,因此它可以快速在屏幕上绘制它,这对于例如PNG 导出(我知道这是 JFreeChart 作者 David Gilbert 想要保留的一个功能),但是当购物车尺寸变化太大时,显示效果不佳。
有没有办法告诉 JFreeChart 在容器调整大小时以某种方式重新呈现图表?
这是 SSCCE:
public static void main(String[] args) {
JFrame frm = new JFrame("JFreeChart resizing");
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CategoryDataset ds = new DefaultCategoryDataset();
JFreeChart chart = ChartFactory.createLineChart("Title", "X axis", "Y axis", ds);
ChartPanel cp = new ChartPanel(chart);
frm.getContentPane().add(cp, BorderLayout.CENTER);
frm.pack();
frm.setVisible(true);
}
Solving Common Layout Problems 建议,“确保您的组件的容器使用尊重组件请求大小的布局管理器。”您的片段使用 BorderLayout.CENTER
,这是一个不错的选择:它允许 ChartPanel
在调整框架大小时平滑地调整大小,但它会忽略面板的最小尺寸。最终,出现重采样伪像和失真。当您想保留调整大小行为时,一种方法是将图表面板的最小绘制宽度和高度设置为零,并(可选)相应地限制框架的最小尺寸:
cp.setMinimumDrawWidth(0);
cp.setMinimumDrawHeight(0);
// optionally
f.setMinimumSize(new Dimension(
cp.getMinimumDrawWidth(),
cp.getMinimumDrawHeight()));
绘图宽度和高度也可以在构造函数中指定,如 here 所示。在下面的例子中,注意:
覆盖
getPreferredSize()
to establish the initial preferred size, also discussed here。- 上 仅 构造和操作 Swing GUI 对象
首选尺码:
较小的尺寸:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
/**
* @see
*/
public class ChartTest {
private static final int W = 320;
private static final int H = 240;
private void display() {
JFrame f = new JFrame("JFreeChart Resizing");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CategoryDataset ds = new DefaultCategoryDataset();
JFreeChart chart = ChartFactory.createLineChart(
"Chart Title", "X axis", "Y axis", ds);
ChartPanel cp = new ChartPanel(chart) {
@Override
public Dimension getPreferredSize() {
return new Dimension(W, H);
}
};
f.add(cp, BorderLayout.CENTER);
f.add(new JLabel("Java v" + System.getProperty("java.version")
+ "; JFreeChart 1.5.3", JLabel.CENTER), BorderLayout.PAGE_END);
cp.setMinimumDrawWidth(0);
cp.setMinimumDrawHeight(0);
f.setMinimumSize(new Dimension(cp.getMinimumDrawWidth(), cp.getMinimumDrawHeight()));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new ChartTest()::display);
}
}