的Java jfreechart的剪裁问题

问题描述:

我试图做一个类,使得一个类似的jfreechart的演示拨号。 但是,如果窗口小于打印刻度盘所需的大小,我希望带拨号的框架可以滚动。我使用滚动窗格实现了这一点,但是会发生的是,由于表盘具有重量级组件,因此它们会在视图端口和滚动条之外进行打印,而且我不能那样做。的Java jfreechart的剪裁问题

我写来测试此功能的代码是:

编辑:我做的代码较小试图使它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); 
      } 
     } 

    } 
} 

如果你编译你上面的代码可以看到,它运行时,它看起来不错,但如果它收缩它最终得到了一些在滚动条的表盘部分(重量级的)的。 我能做些什么来解决这个问题?

+0

请使用SSCCE:http://sscce.org/ – StormeHawke

+0

+1 [SSCCE(http://sscce.org/),虽然@StormeHawke是正确的,它可能是一个短一点。 :-) – trashgod

+0

是真的,即时学习。这个问题的一部分是由于我得到的视觉错误不是所有的组件都只有几个,因此我几乎发布了我的代码的所有图形部分。 – jonny

据我所知,没有JFreechart也不org.jfree.chart.plot.dial.*含有重量级组件。您的示例通常会为我调整大小。有几个注意事项:

  • 不要使用setPreferredSize()当你真的要覆盖getPreferredSize(),如图here和讨论here

  • Swing GUI对象应该在event dispatch thread上构建和操纵只有

  • 取代在initial thread上循环播放,请使用javax.swing.Timer来为动画播放速度。

  • 你在不恰当的使用GridBagConstraints。一个简单的垂直GridLayout运作良好,并避免了在面板中的任何set*Size()或滚动窗格中的需要。

    final JPanel jpanel1 = new JPanel(new GridLayout(0, 1)); 
    
  • JFrame可以设置默认的关闭操作,从而消除了WindowListener的需要。

    test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    
+0

我真的认为它确实有很重的组件,即渐变背景和表盘形状等。注意,如果缩小它,只会覆盖一些东西。 感谢您的所有建议。我要补充一点,在上面的代码主要是只是一个快速和肮脏的测试为主,不以任何方式涉及到如何使用它除了视觉错误仍然 – jonny

+0

对不起,我不能重现你描述这有利于同步的效果,问题;在你的平台上尝试'invokeLater()'。 – trashgod

+0

那么,我试图获得足够的声望来发布图片,那么它应该很容易显示出问题。对我而言,这与我选择的平台无关。 我没有尝试过的是使用JFreeChart的最新发行版,因为这是一个商业产品,我们只有jfreechart的旧版本的许可证 – jonny