2016-12-11 3 views
0

したがって、リジッド部分がJPanel(キャンバス)を内部に持つJScrollPane(mainGUIクラス)の単純なグラフィックGUIを作成しました。ボックスクラスを使用して(ボックスクラスを使用して)描画し、それを実行しようとすると、スクロールするときにボックスタイプのレンダリングが遅すぎたり、何か説明が難しいWindowsXPグラフィックエラーが発生します。スクロールした後、一様でないグリフの描画を取得するにはどうすればよいですか?レンダリングオプションなどはありますか?JScrollPane内のJPanelスクロール中にグラフィックスの不具合が発生する

コード:事前に

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 


public class Grafin{ 
    public static void main(String args[]){ 
     mainGUI gui = new mainGUI(); 
    } 
} 

class mainGUI{ 
    private JFrame mainFrame; 
    private JPanel toolsPanel; 
    private JPanel canvasPanel; 

    public mainGUI(){ 
     try{ 
      UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); 
     }catch(Exception e){ 
      System.out.println(e.getMessage()); 
     } 

     mainFrame = new JFrame("Grafin | untitled"); 
     mainFrame.setLayout(new GridBagLayout()); 
     mainFrame.setSize(920, 580); 
     mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     mainFrame.setLocationRelativeTo(null); 
     mainFrame.setVisible(true);  

     loadGUI(); 
    } 

    public void loadGUI(){ 
     GridBagConstraints c = new GridBagConstraints(); 

     //toolsPanel (izq) y canvasPanel (der) dentro de mainFrame 
     toolsPanel = new JPanel(new GridBagLayout()); 
     toolsPanel.setPreferredSize(new Dimension(250,580)); 

     c.gridx = 0; 
     c.gridy = 0; 
     c.weightx = 0.1; 
     c.weighty = 1; 
     c.fill = GridBagConstraints.BOTH; 
     mainFrame.add(toolsPanel, c); 


     canvasPanel = new JPanel(new GridBagLayout()); 
     canvasPanel.setBackground(Color.white); 
     canvasPanel.setPreferredSize(new Dimension(1500,1000)); 

     JScrollPane canvasScroll = new JScrollPane(canvasPanel); 
     canvasScroll.setPreferredSize(new Dimension(670,580)); 

     c.gridx = 1; 
     c.gridy = 0; 
     c.weightx = 0.9; 
     mainFrame.add(canvasScroll, c); 
     canvasScroll.setSize(canvasScroll.getPreferredSize()); 
     canvasScroll.setBackground(Color.white); 

     //CanvasPanel: 
     c.gridx = 0; 
     c.gridy = 0; 
     c.weightx = 1; 
     c.weighty = 1; 

     Box b1 = new Box(10, 200, 30, 128); 
     Box b2 = new Box(200, 10, 120, 40); 
     canvasPanel.add(b1, c); 
     canvasPanel.add(b2, c); 
     mainFrame.pack(); 
    } 
} 

    class Box extends JPanel{ 
    private Color borderColor; 
    private Color fillColor; 
    public int x; 
    public int y; 
    public int width; 
    public int height; 

    public Box(){ 
     borderColor = Color.black; 
     fillColor = new Color(242, 242, 242); 
     x = y = 1; 
     width = height = 30; 
    } 

    public Box(int px, int py, int w, int h){ 
     x = px; 
     y = py; 
     borderColor = Color.black; 
     fillColor = new Color(242, 242, 242); 
     width = w; 
     height = h; 
    } 

    public void changeFillColor(Color c){ 
     fillColor = c; 
    } 

    public void changeBorderColor(Color c){ 
     borderColor = c; 
    } 

    public void paint(Graphics g){ 
     g.setColor(fillColor); 
     g.fillRect(x, y, width, height); 
     g.setColor(borderColor); 
     g.drawRect(x, y, width, height); 
    } 
} 

おかげ 幸せな休日

答えて

4

まず第一に、あなたは間違った絵メソッドをオーバーライドしています。 JPanelのpaintメソッドをオーバーライドするのではなく、paintComponentメソッドをオーバーライドする必要があります。これは、より具体的なペイント方法であり、デフォルトでダブルバッファリングを持ち、アニメーション(スクロールでやっていること)を行うときにプラスです。

paintComponentをオーバーライドする場合はsuper.paintComponent(g)、塗料を(間違って)オーバーライドする場合はsuper.paint(g)をオーバーライドしてsuperのペインティングメソッドを呼び出さないことがさらに重要です。これにより、JPanelが汚れたピクセルをクリーニングできなくなります。

その他の問題:GridBagLayoutを使用するコンポーネントに2つのコンポーネントを追加していますが、どちらのコンポーネントにも同じGridBagConstraintsを使用しています。

また、ボックスクラスは論理クラスであり、コンポーネントクラスではありません。言い換えると、Swing GUIコンポーネントを拡張してはならず、canvasPanel内に描画する必要があります。例えば

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.util.ArrayList; 
import java.util.List; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class Grafin2 extends JPanel { 
    private static final int PREF_W = 920; 
    private static final int PREF_H = 580; 
    private static final Dimension TOOLS_SIZE = new Dimension(250, PREF_H); 
    private static final Dimension CANVAS_SIZE = new Dimension(1500, 1000); 
    private JPanel toolsPanel = new JPanel(); 
    private CanvasPanel canvasPanel = new CanvasPanel(); 

    public Grafin2() { 
     MyBox box1 = new MyBox(10, 200, 30, 128); 
     MyBox box2 = new MyBox(200, 10, 120, 40); 

     box1.changeFillColor(new Color(255, 120, 120)); 
     box2.changeFillColor(new Color(220, 220, 255)); 

     canvasPanel.addMyBox(box1); 
     canvasPanel.addMyBox(box2); 

     toolsPanel.setPreferredSize(TOOLS_SIZE); 
     canvasPanel.setBackground(Color.white); 
     canvasPanel.setPreferredSize(CANVAS_SIZE); 
     JScrollPane canvasScroll = new JScrollPane(canvasPanel); 

     setLayout(new BorderLayout()); 
     add(toolsPanel, BorderLayout.LINE_START); 
     add(canvasScroll, BorderLayout.CENTER); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
      return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 

    private class CanvasPanel extends JPanel { 
     // a collection to hold all the boxes 
     private List<MyBox> boxes = new ArrayList<>(); 

     public void addMyBox(MyBox myBox) { 
      boxes.add(myBox); 
     } 

     @Override // again, this is the proper painting method 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); // never forget this! 
      for (MyBox myBox : boxes) { 
       myBox.draw(g); // draw all the boxes that we hold 
      } 
     } 
    } 

    private static void createAndShowGui() { 
     Grafin2 mainPanel = new Grafin2(); 

     JFrame frame = new JFrame("Grafin2"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
} 

// this is a logical class, **not** a component class. 
class MyBox { 
    private Color borderColor; 
    private Color fillColor; 
    public int x; 
    public int y; 
    public int width; 
    public int height; 

    public MyBox() { 
     borderColor = Color.black; 
     fillColor = new Color(242, 242, 242); 
     x = y = 1; 
     width = height = 30; 
    } 

    public MyBox(int px, int py, int w, int h) { 
     x = px; 
     y = py; 
     borderColor = Color.black; 
     fillColor = new Color(242, 242, 242); 
     width = w; 
     height = h; 
    } 

    public void changeFillColor(Color c) { 
     fillColor = c; 
    } 

    public void changeBorderColor(Color c) { 
     borderColor = c; 
    } 

    public void draw(Graphics g) { 
     // no need to call a super method 
     // because there is none for this class 
     g.setColor(fillColor); 
     g.fillRect(x, y, width, height); 
     g.setColor(borderColor); 
     g.drawRect(x, y, width, height); 
    } 
} 
+0

後半の応答のため申し訳ありませんが、決勝で忙しかったです。あなたの答えをありがとう、それを試してみると、それが動作するかどうかを確認してください。 –

+0

アップデート:これは私がしたいように機能します。再びありがとう。 –

+0

@ Luis_V:私に戻ってくれてありがとう、うまくいきました。 –

関連する問題