0

新しく追加された JPanels に関係するすべての処理が、以前のように for ループ内ではなく、addBlock(..) と呼ばれる独自のメソッド内にあるように、JPanels 四角形を描画するペイントの for ループ メソッドを変更しました。私がそれをした後、JPanelsはもう表示されません。

基本的に、私がこのプログラムでやろうとしているのは、必要に応じて JPanel (60x60 ブロックで表される) を追加および削除できるようにすることです。そのため、私は ArrayList を使用しています... 後で paint() メソッドを呼び出すだけで、ArrayList にある要素の数に基づいて再描画されます。これは初期段階であり、私はまだ新しいので、より効率的な方法があるかどうかさえわかりません. 今のところ、私は物事を表示したいだけです。

これが私のコードです:

import java.awt.*;
import java.util.ArrayList;
import javax.swing.*;

class TestApp extends JFrame{
    JFrame frame = new JFrame();
    ArrayList<JPanel> grid = new ArrayList<JPanel>();

    private static int amount = 10;

    private void paint()
    {   
        for(int i = 0, x = 0, y = 0; i < amount; i++, x += 62)
        {
            addBlock(i, x, y);
        }
    }

    //Adds a block
    private void addBlock(int index, int x, int y){
        int height = 60;
        int width = 60;

        grid.add(new JPanel());
        frame.add(grid.get(index));

        (grid.get(index)).setVisible(true);
        (grid.get(index)).setBounds(x, y, width, height);
    }  

    //Removes a block
    private void removeFrame(int index){
        frame.remove(grid.get(index));
        grid.remove(index);
    }  

    //Default Constructor (sets up JFrame)
    TestApp(){ 
        frame.setLayout(null);
        frame.setPreferredSize(new Dimension(600, 300));
        frame.setTitle("Test Program");
        frame.setBackground(Color.WHITE); 
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setAlwaysOnTop(rootPaneCheckingEnabled);
        frame.setResizable(true);
        frame.setVisible(true);
    }

    public static void main(String [] args) {
        TestApp program = new TestApp();
        program.paint();
    }
}

アイデアや提案はありますか?

編集:修正および改善されたコードは次のとおりです。まだ十分な調査を行っていないため、提案された他のことはまだ実装していません。

package my;

import java.awt.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.border.LineBorder;

class TestApp extends JFrame{
    JFrame frame = new JFrame();
    ArrayList<JButton> grid = new ArrayList<JButton>();

    private static int amount = 46;
    private static int counter = 0;

    private void paintGrid()
    {   
        for(int i = 0, y = 4; i < ((amount / 10) + (amount % 10)); i++, y += 104)
        {
            for(int j = 0, x = 4; j < 10 && (counter < amount); j++, x += 84)
            {
                addBlock(counter, x, y);
                counter++;
            }
        }
    }

    //Adds a block
    private void addBlock(int index, int x, int y){
        int height = 100;
        int width = 80;

        grid.add(new JButton());
        (grid.get(index)).setBackground(Color.YELLOW);
        (grid.get(index)).setBorder(new LineBorder(Color.BLACK));
        (grid.get(index)).setVisible(true);
        (grid.get(index)).setBounds(x, y, width, height);

        frame.add(grid.get(index));
    }  

    //Removes a block
    private void removeBlock(int index){
        frame.remove(grid.get(index));
        grid.remove(index);
    }  

    //Default Constructor (sets up JFrame)
    TestApp(){ 
        frame.setLayout(null);
        frame.setPreferredSize(new Dimension(850, 600));
        frame.setTitle("Test Program");        
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setAlwaysOnTop(rootPaneCheckingEnabled);
        frame.setResizable(false);
        frame.setVisible(true);
    }

    public static void main(String [] args) {
        TestApp program = new TestApp();
        program.paintGrid();
    }
}
4

4 に答える 4

2

コンポーネントでカスタム ペイントを行うには、次のようなメソッドを作成する必要があります。

public void paintComponent(Graphics g)

これは、コンポーネントを描画するために Swing によって呼び出される唯一のメソッドです。

つまり、このメソッドは、クラスのメソッドを使用して既存のUI コンポーネントpaintComponent()に何かを描画することを目的としています。現在の UI に追加する新しいコンポーネントを作成しないでください。Graphics

グリッド内の単一要素のカスタム ペインティングを行う JPanel のサブクラスを作成することをお勧めします。次に、これらのカスタム JPanel を必要な数だけ JFrame に追加します。

于 2013-05-09T05:53:07.017 に答える
2
  1. paint() / paintComponent() メソッド内に JComponents を追加しない

  2. paint() / paintComponent() は、API で実装されたメソッドから内部的に、すべてのマウス & キー イベントの後に呼び出されます

  3. 継続者は、実行時に JComponent が追加されたことを認識していないため、 revalidate() と repaint() を呼び出す必要があります

  4. Oracle チュートリアル 2D グラフィックスをお読みください

  5. (空またはグラフィックを含む) JPanel はデフォルトでサイズを返しません

于 2013-05-09T05:59:32.677 に答える
2

問題は、パネルが追加されていないことをどのように確認できるかということです。親パネルと同じ色ですか?

addBlock各パネルを強調表示する方法を変更してみてください...

private void addBlock(int index, int x, int y){
    int height = 60;
    int width = 60;

    JPanel panel = new JPanel()
    panel.setBorder(new LineBorder(Color.BLACK));
    grid.add(panel);
    frame.add(grid.get(index));

    (grid.get(index)).setVisible(true);
    (grid.get(index)).setBounds(x, y, width, height);
}  

アドバイスとして、nullレイアウトは魅力的に見えますが、1 つまたは複数のレイアウト マネージャーをよく考えて適用すると、より多くの時間と労力が費やされることになります...

ps -paint他の人を際限なく混乱させるので、呼び出されたメソッドの使用も避けます。

于 2013-05-09T05:54:59.097 に答える
1
  1. を指定しませんLayoutManagerSwing Layout Managerは、最適なレイアウトの概要を提供し、frame.setLayout(null);Null レイアウトを置き換えることは適切な選択ではありません。

  2. を追加しますJPanels。動いていても何も見えません。アプリを修正したところ、 と で動作しFlowLayoutますJLabels

    import java.awt.*;
    import java.util.ArrayList;
    import javax.swing.*;
    
    public class TestApp extends JFrame{
        JFrame frame = new JFrame();
        ArrayList<JLabel> grid = new ArrayList<JLabel>();
    
        private static int amount = 10;
    
        private void paint()
        {   
            for(int i = 0, x = 0, y = 0; i < amount; i++, x += 62)
            {
                addBlock(i, x, y);
            }
        }
    
        //Adds a block
        private void addBlock(int index, int x, int y){
            int height = 60;
            int width = 60;
    
            grid.add(new JLabel("hello"));
            frame.add(grid.get(index));
    
            (grid.get(index)).setVisible(true);
            (grid.get(index)).setBounds(x, y, width, height);
    
            frame.revalidate();
            frame.repaint();
        }  
    
        //Removes a block
        private void removeFrame(int index){
            frame.remove(grid.get(index));
            grid.remove(index);
        }  
    
        //Default Constructor (sets up JFrame)
        TestApp(){ 
            frame.setLayout(new FlowLayout());
            frame.setPreferredSize(new Dimension(600, 300));
            frame.setTitle("Test Program");
            frame.setBackground(Color.WHITE); 
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
            frame.setAlwaysOnTop(rootPaneCheckingEnabled);
            frame.setResizable(true);
            frame.setVisible(true);
        }
    
        public static void main(String [] args) {
            TestApp program = new TestApp();
            program.paint();
    }
    }
    
于 2013-05-09T06:03:29.493 に答える