1

I am trying to make a class that makes a dial similar to the one in the jfreechart demos. 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)

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 . This bug is not reproducible with the current version of 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?

jonny
  • 11
  • 4
  • Please use a SSCCE : http://sscce.org/ – StormeHawke Oct 24 '13 at 18:39
  • +1 for [sscce](http://sscce.org/), although @StormeHawke is right that it could be a little shorter. :-) – trashgod Oct 24 '13 at 20:41
  • true, im learning though. And part of the issue is due to the fact that the visual bug I get isn't with all the components only a few hence me posting almost all the graphical part of my code. – jonny Oct 24 '13 at 21:19

1 Answers1

1

To my knowledge, neither JFreechart nor org.jfree.chart.plot.dial.* contain heavyweight components. 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.

  • Swing GUI objects should be constructed and manipulated only on the event dispatch thread.

  • Instead of looping on the initial thread, use a javax.swing.Timer to pace animation.

  • Your use of GridBagConstraints in not appropriate. A simple vertical GridLayout works well and obviates the need for any set*Size() in the panel or scroll pane.

    final JPanel jpanel1 = new JPanel(new GridLayout(0, 1));
    
  • JFrame can set the default close operation, which eliminates the need for a WindowListener.

    test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I really think it does have heavy components, namely for things like the gradient background and the dial shape. Notice how if you shrink it you get only some things overlaped. Thanks for all the suggestions. I must add that the main in the code above is just a quick and dirty test main, in any way not related to how its used except the visual bug remains – jonny Oct 24 '13 at 20:48
  • Sorry, I can't reproduce the effect you describe, which favors a synchronization problem; try `invokeLater()` on your platform. – trashgod Oct 25 '13 at 00:42
  • Well, I'm trying to get enough reputation to post pictures, then it should be easy to show the problem. For me, this is independent of the platform I pick. What I haven't tried was to use the most recent distribution of JFreeChart, since this is for a comercial product we only have licence for slightly old version of jfreechart – jonny Oct 25 '13 at 06:41
  • The issue was indeed with an old version of JFreechart. I'll ask my we can update to a new version otherwise I'll have to re-ask providing this extra info. Currently we have the license to use 1.0.9 version of JFreechart. – jonny Oct 25 '13 at 07:29
  • Ah, good to know. The license is LGPL; you can always upgrade without charge, but you'll want to re-test and do configuration management. – trashgod Oct 25 '13 at 11:00