Java jfreechart 裁剪问题

标签 java swing jscrollpane jfreechart clipping

我正在尝试创建一个类,使表盘与 jfreechart 演示中的表盘类似。 但是,如果窗口变得比打印表盘所需的小,我希望带有表盘的框架可以滚动。我使用滚动 Pane 实现了这一点,但发生的情况是,由于表盘具有重量级组件,它们会在 View 端口之外和滚动条上打印,而我无法拥有它。

我为测试此功能而编写的代码是:

编辑:我缩小了代码,试图使其成为 SSCCE(这是我第一次发布问题,如果它仍然太大,很抱歉)

编辑2:我意识到这是我正在使用(并且必须使用)的 jfreechart 发行版(即 1.0.9 )中的一个问题。当前版本的 jfreechart 无法重现此错误。

import java.awt.*;
import javax.swing.JPanel;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.dial.*;
import org.jfree.data.general.DefaultValueDataset;
import org.jfree.ui.*;

public class DialDoubleNeedle extends JPanel{

    private DefaultValueDataset dataset1;
    private DefaultValueDataset dataset2;
    private JFreeChart chart;
    public DialDoubleNeedle() {
        super();

        this.dataset1 = new DefaultValueDataset(0.10);
        this.dataset2 = new DefaultValueDataset(0.50);

        // get data for diagrams
        DialPlot plot = new DialPlot();
        plot.setView(0.0, 0.0, 1.0, 1.0);
        plot.setDataset(0, this.dataset1);
        plot.setDataset(1, this.dataset2);
        StandardDialFrame dialFrame = new StandardDialFrame();
        dialFrame.setBackgroundPaint(Color.lightGray);
        dialFrame.setForegroundPaint(Color.darkGray);        
        plot.setDialFrame(dialFrame);

        GradientPaint gp = new GradientPaint(new Point(), 
                new Color(255, 255, 255), new Point(), 
                new Color(170, 170, 220));

        DialBackground db = new DialBackground(gp);
        db.setGradientPaintTransformer(new StandardGradientPaintTransformer(GradientPaintTransformType.VERTICAL));
        plot.setBackground(db);
        DialTextAnnotation annotation1 = new DialTextAnnotation("m/s");
        annotation1.setFont(new Font("Dialog", Font.BOLD, 14));
        annotation1.setRadius(0.7);

        plot.addLayer(annotation1);

        DialValueIndicator dvi = new DialValueIndicator(0);
        dvi.setFont(new Font("Dialog", Font.PLAIN, 10));
        dvi.setOutlinePaint(Color.darkGray);
        dvi.setRadius(0.60);
        dvi.setAngle(-103.0);
        dvi.setNumberFormat(new java.text.DecimalFormat("0.00"));
        plot.addLayer(dvi);

        DialValueIndicator dvi2 = new DialValueIndicator(1);
        dvi2.setFont(new Font("Dialog", Font.PLAIN, 10));
        dvi2.setOutlinePaint(Color.red);
        dvi2.setRadius(0.60);
        dvi2.setAngle(-77.0);
        dvi2.setNumberFormat(new java.text.DecimalFormat("0.00"));
        plot.addLayer(dvi2);

        StandardDialScale scale = new StandardDialScale(0, 1, -120, -300, 0.1, 5);
        scale.setTickRadius(0.88);
        scale.setTickLabelOffset(0.15);
        scale.setTickLabelFont(new Font("Dialog", Font.PLAIN, 14));
        plot.addScale(0, scale);

        StandardDialScale scale2 = new StandardDialScale(0, 1, -120, -300, 0.1, 5);
        scale2.setTickRadius(0.50);
        scale2.setTickLabelOffset(0.15);
        scale2.setTickLabelFont(new Font("Dialog", Font.PLAIN, 10));
        scale2.setMajorTickPaint(Color.red);
        plot.addScale(1, scale2);
        plot.mapDatasetToScale(1, 1);

        DialPointer needle2 = new DialPointer.Pin(1);
        needle2.setRadius(0.55);
        plot.addLayer(needle2);

        DialPointer needle = new DialPointer.Pointer(0);
        plot.addLayer(needle);

        DialCap cap = new DialCap();
        cap.setRadius(0.10);
        plot.setCap(cap);

        chart = new JFreeChart(plot);
        chart.setTitle("Title");
        ChartPanel cp1 = new ChartPanel(chart);
        add(cp1);


    }

    void setTitle(String title){
        chart.setTitle(title);
        return;
    }


    public static void main(final String args[]) {
        final javax.swing.JFrame test = new javax.swing.JFrame();
        test.addWindowListener(new java.awt.event.WindowAdapter() {
            @Override
            public void windowClosing(final java.awt.event.WindowEvent e) {
                System.exit(0);
            }
        });

        final JPanel jpanel1 = new JPanel();

        DialDoubleNeedle app1 = new DialDoubleNeedle();
        app1.setTitle("Tittle 1");

        jpanel1.add(app1);

        final javax.swing.JScrollPane scrollPane = new javax.swing.JScrollPane();

        scrollPane.setViewportView(jpanel1);

        test.getContentPane().add(scrollPane);
        test.pack();
        test.setVisible(true);


        int i;
        Number v;   
        for(i=0; i<1000000000; i++){
            if(i==(1000000000-1)){
                i=0;
                v=app1.dataset1.getValue();
                app1.dataset1.setValue(v.doubleValue()+0.01);
            }
        }

    }
}

如果您编译上面的代码,您可以看到,当它运行时,它看起来很好,但是如果您缩小它,它最终会在滚动条上得到一些刻度盘部分(重量级的部分)。 我可以做什么来解决这个问题?

最佳答案

据我所知,JFreechartorg.jfree.chart.plot.dial.* 都不包含重量级组件。您的示例对我来说通常会调整大小。一些注意事项:

  • 当您确实想要覆盖 getPreferredSize() 时,请勿使用 setPreferredSize(),如图 here并讨论了here .

  • Swing GUI 对象应该event dispatch thread 上构建和操作。 .

  • 而不是在 initial thread 上循环,使用javax.swing.Timer调整动画速度。

  • 您对 GridBagConstraints 的使用不恰当。简单的垂直 GridLayout 效果很好,并且无需在面板或滚动 Pane 中使用任何 set*Size()

    final JPanel jpanel1 = new JPanel(new GridLayout(0, 1));
    
  • JFrame可以设置默认的关闭操作,这样就不需要WindowListener了。

    test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    

关于Java jfreechart 裁剪问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19573922/

相关文章:

java - GridBagLayout 中的 JPanel 位置不正确

java - 如何提高 JScrollPane 的慢速滚动速度?

java - JTextArea 的 JScrollPane 不起作用;不会滚动

java - 有时数据不会插入到表中

java - 通过字段 'personRepository' 表示的不满足的依赖关系;嵌套异常是 org.springframework.beans.factory.BeanCreationException :

java - 在窗口中显示图像时出现问题

Java Swing JTextArea 行号

java - 清除特定的数组列表而不是它的所有副本

java - 如何以编程方式覆盖/更改 Java 中认可的标准?

Java Swing : Action Event to submit multiple variables