【问题标题】:Having difficulty displaying JPanels that were added using for() loop and a method. Java难以显示使用 for() 循环和方法添加的 JPanel。爪哇
【发布时间】:2013-05-09 05:47:26
【问题描述】:

我修改了我的paint的for循环方法,该方法将JPanels方块绘制到与新添加的JPanels有关的所有内容都不像以前那样在for循环中,而是在它自己的称为addBlock(.. )。在我这样做之后,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();
    }
}

【问题讨论】:

    标签: java swing jframe jpanel awt


    【解决方案1】:

    问题是,您怎么知道没有添加面板?它们与父面板的颜色相同吗?

    尝试更改您的 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 布局看起来很有吸引力,但它们最终会花费您更多的时间和精力,然后一个或多个布局管理器的深思熟虑的应用程序将...

    ps - 我也会避免使用名为 paint 的方法,因为它们会让其他人感到困惑。

    【讨论】:

    • 哈!先生,您说的完全正确。在创建新方法时,我完全忘记了颜色。它现在就像一个魅力。非常非常非常非常感谢! ;)
    • 嘿,是的,这样的解脱.. 我自己有那么一会儿感觉有点生气。 :)
    • 我刚刚和我的高级开发人员度过了一个 时刻,已经解决了 6 个小时的问题,他在 30 秒内用 4 行代码解决了这个问题……看不到树森林:P
    • 关于您的最后几个建议:是的,我将我的重命名为paintGrid ...因为它对我正在做的事情更有意义。我将看看布局管理器...我是新手,所以我第一次听说它们时感到困惑。
    【解决方案2】:

    为了对组件进行自定义绘制,您需要创建一个如下所示的方法:

    public void paintComponent(Graphics g)
    

    这是Swing调用来绘制组件的唯一方法。

    话虽如此,paintComponent() 方法旨在使用Graphics 类的方法在现有 UI 组件上绘制一些东西。您不应创建新组件以添加到当前 UI。

    我建议您创建一个 JPanel 的子类,它为您的网格中的 single 元素进行自定义绘制。然后将任意数量的这些自定义 JPanel 添加到 JFrame。

    【讨论】:

      【解决方案3】:
      1. 永远不要在paint()/paintComponent()方法中添加JComponents

      2. paint()/paintComponent() 在所有鼠标和按键事件之后调用,内部来自 API 中实现的方法

      3. continer 不知道在运行时添加了任何 JComponent,必须调用 revalidate() & repaint()

      4. 请阅读Oracle tutorial 2D Graphics

      5. (空或包含图形)JPanel 默认从不返回任何大小

      【讨论】:

      • 你把我指向那个链接真的很棒,它有一些我想知道的东西,并且想在处理这个程序时实现,打印。他们有一个教程! :D 谢谢你,先生。
      【解决方案4】:
      1. 您没有指定任何LayoutManagerSwing Layout Manager 为您提供最适合您的概览,并替换 frame.setLayout(null); 空布局不是一个好的选择!

      2. 您添加 empty JPanels。即使它有效,你也不会看到任何东西。我修改了应用程序,它适用于FlowLayoutJLabels

        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();
        }
        }
        

      【讨论】:

      • 谢谢,我一定会更多地研究布局管理器。
      猜你喜欢
      • 1970-01-01
      • 2013-05-22
      • 1970-01-01
      • 1970-01-01
      • 2018-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-14
      相关资源
      最近更新 更多