2017-06-06 34 views
0

我在Graphics drawString方法中遇到了问题。简而言之,我观察到Linux上的意外行为drawString,如果面板大小很大,字符串会变得混乱。大型JPanel上的drawString在Linux上变得凌乱,但在Windows上却不行

作为一个例子。我已经修改了ScrollDemo2类从Oracle的拉线在drawingPane

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 

import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 

public class ScrollDemo2 extends JPanel 
          { 
    private Dimension area; 
    private JPanel drawingPane; 

    public ScrollDemo2() { 
     super(new BorderLayout()); 

     area = new Dimension(100000,1000); 

     drawingPane = new DrawingPane(); 
     drawingPane.setBackground(Color.white); 
     drawingPane.setPreferredSize(area); 
     drawingPane.revalidate(); 
     drawingPane.repaint(); 

     JScrollPane scroller = new JScrollPane(drawingPane); 
     scroller.setPreferredSize(new Dimension(500,500)); 

     add(scroller, BorderLayout.CENTER); 
    } 

    public class DrawingPane extends JPanel { 
     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      // drawString gives correct results in Windows but gives messy strings in Linux; drawLine gives correct lines in both Windows and Linux 
      for (int i = 0; i < 100000; i += 100) 
       g.drawString("Mark " + i, i, 20); 
      for (int i = 0; i < 100000; i += 100) 
       g.drawLine(i, i % 1000/10 + 25, i, i % 1000/10 + 35); 

     } 

    } 


    private static void createAndShowGUI() { 
     JFrame frame = new JFrame("ScrollDemo2"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JComponent newContentPane = new ScrollDemo2(); 
     newContentPane.setOpaque(true); 
     frame.setContentPane(newContentPane); 

     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 

计划在Windows 7

程序会显示正确的字符串运行在Windows 7

计划在Linux上运行14.04

该程序在Linux上显示杂乱的字符串。

除了drawString方法外,还增加了drawLine方法,并且drawLine方法在Windows和Linux中均可正常工作。

为什么?我应该如何重写代码来解决Linux上的问题?

+0

不知道问题出现的原因,但如果这是我的程序,我会在BufferedImage上绘制一个静态(不变的)图像,然后将该图像显示在我的JPanel的paintComponent方法中或作为ImageIcon一个JLabel。 –

+0

尝试'g.setColor(Color.white); g.fillRect(0,0,this.width,this.height);'绘制字符串之前 – Oneiros

+0

@Oneiros面板在Windows和Linux中都会变成白色。 (没有正确的字符串,也不会显示杂乱的字符串) –

回答

2

正如注释中所述,如果绘制静态(稳定的不变背景图像),请使用BufferedImage。例如:

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.image.BufferedImage; 

import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 

public class ScrollDemo2B extends JPanel 
          { 
    private static final int IMG_W = 100000; 
    private static final int IMG_H = 1000; 
    // private Dimension area; 
    private JPanel drawingPane; 
    private BufferedImage img = new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_ARGB); 

    public ScrollDemo2B() { 
     super(new BorderLayout()); 

     Graphics2D g2 = img.createGraphics(); 
     g2.setColor(Color.BLACK); 
     for (int i = 0; i < 100000; i += 100) { 
      g2.drawString("Mark " + i, i, 20); 
     } 
     for (int i = 0; i < 100000; i += 100) { 
      g2.drawLine(i, i % 1000/10 + 25, i, i % 1000/10 + 35); 
     } 
     g2.dispose(); 

     drawingPane = new DrawingPane(); 
     drawingPane.setBackground(Color.white); 
     drawingPane.revalidate(); 
     drawingPane.repaint(); 

     JScrollPane scroller = new JScrollPane(drawingPane); 
     scroller.setPreferredSize(new Dimension(500,500)); 

     add(scroller, BorderLayout.CENTER); 
    } 

    public class DrawingPane extends JPanel { 
     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      if (img != null) { 
       g.drawImage(img, 0, 0, this); 
      } 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      if (isPreferredSizeSet() || img == null) { 
       return super.getPreferredSize(); 
      } 
      int w = img.getWidth(); 
      int h = img.getHeight(); 
      return new Dimension(w, h); 
     } 

    } 


    private static void createAndShowGUI() { 
     JFrame frame = new JFrame("ScrollDemo2"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JComponent newContentPane = new ScrollDemo2B(); 
     newContentPane.setOpaque(true); 
     frame.setContentPane(newContentPane); 

     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 

然后,如果你有手机精灵或动态画面,则可以将方法的paintComponent中绘制它们。

+0

它在Windows中使用正确的字符串和行,但它不能在Linux上显示,只显示空白的白色面板(没有字符串和行)。感谢虽然教我另一种策略:) –

相关问题