简体   繁体   English

Java jfreechart裁剪问题

[英]Java jfreechart clipping issue

I am trying to make a class that makes a dial similar to the one in the jfreechart demos. 我正在尝试制作一个与jfreechart演示中的拨号类似的类。 However I want the frame with the dials to be scrollable if the window becomes smaller than that needed to print the dial. 但是,如果窗口变得小于打印拨盘所需的窗口,我希望拨盘的框架可滚动。 I achieved this using the Scroll Pane but what happens is that due to the fact that the dial has heavyweight components they print outside the view port and over the scroll bar and I cannot have that. 我使用“滚动窗格”实现了这一点,但是发生的是由于表盘具有重量级组件,因此它们在视口外部和滚动条上打印,而我无法做到这一点。

The code I wrote to test this feature is: 我编写的用于测试此功能的代码是:

EDIT: I made the code smaller trying to make it SSCCE (It is the first time i post a question so sorry if its still too big) 编辑:我使代码变小,试图使其成为SSCCE(这是我第一次发布问题,对不起,如果它仍然太大)

EDIT 2: I've realized this is an issue in the jfreechart distribution I'm using (and have to use) which is the 1.0.9 . 编辑2:我已经意识到这是我正在使用(必须使用)的1.0.9的jfreechart发行版中的一个问题。 This bug is not reproducible with the current version of jfreechart. 当前版本的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);
            }
        }

    }
}

If you compile the code above you can see that when it runs it looks fine but if you shrink it it eventually gets some of the dial parts (the heavyweight ones) over the scroll bars. 如果编译上面的代码,则可以看到它运行时看起来不错,但是如果缩小它,最终它会在滚动条上得到一些刻度盘部分(重量级的部分)。 What can I do to fix this? 我该怎么做才能解决此问题?

To my knowledge, neither JFreechart nor org.jfree.chart.plot.dial.* contain heavyweight components. 据我所知, JFreechartJFreechart org.jfree.chart.plot.dial.*都不包含重量级的组件。 Your example resizes normally for me. 您的示例对我来说大小正常。 A few notes: 一些注意事项:

  • Don't use setPreferredSize() when you really mean to override getPreferredSize() , as shown here and discussed here . 不要使用setPreferredSize()当你真的要重写getPreferredSize()如图所示这里讨论在这里

  • Swing GUI objects should be constructed and manipulated only on the event dispatch thread . 只能事件分发线程上构造和操作Swing GUI对象。

  • Instead of looping on the initial thread , use a javax.swing.Timer to pace animation. 与其在初始线程上循环,不如使用javax.swing.Timer来加速动画。

  • Your use of GridBagConstraints in not appropriate. 您对GridBagConstraints使用不合适。 A simple vertical GridLayout works well and obviates the need for any set*Size() in the panel or scroll pane. 一个简单的垂直GridLayout可以很好地工作,并且不需要在面板或滚动窗格中使用任何set*Size()

     final JPanel jpanel1 = new JPanel(new GridLayout(0, 1)); 
  • JFrame can set the default close operation, which eliminates the need for a WindowListener . JFrame可以设置默认的关闭操作,从而无需WindowListener

     test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM