【问题标题】:Can't update JLabel array无法更新 JLabel 数组
【发布时间】:2021-11-08 21:09:15
【问题描述】:

我正在编写一个具有JLabel 数组的东西,该数组在第一个索引中有一些东西,然后检测到将东西向右移动的右键。基本上,[x][][][][][][] 开始,然后如果我按右键,它会切换到 [][x][][][][][]。目前,我无法让JLabel 正确更新。一开始它显示正确,但是当我按下正确的键时,整个事情就搞砸了。即,它是这样开始的:

(我有数字来衡量变化,当我解决这个问题时它们会消失)

这是对的,但是当我按下正确的键时,一切都消失了(只是空白。)但是,我在控制台中的测试仍然给了我正确的值。

数字甚至没有显示出来:/

以下是相关代码:

    public Template() {     
        for (int i = 0; i < 7; i++) {
            positions[i] = new JLabel();
            positions[i].setFont(new Font("Times New Roman", Font.PLAIN, 15));
            System.out.println("Yay");
        }

        // I initialize my JLabel array here instead of below because if I don't do this, there's no change whatsoever if I press the right key. I'm not sure if I did it correctly, though.
        initialize(p1, 0);
    }
    
    private void initialize(String p, int index) {      
        frame = new JFrame();
            
        JPanel header = new JPanel();
        header.setBackground(Color.WHITE);
            
        GridBagLayout gbl = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
        header.setLayout(gbl);
        header.setPreferredSize(new Dimension(400, 50));
        c.fill = GridBagConstraints.HORIZONTAL;
        
        for (int i = 0; i < 7; i++) {
            if (i == index) {
                positions[i].setText(p + "");
                System.out.println("indexed set");
            } else {
                positions[i].setText("" + i);
                System.out.println(positions[i].getText());
                System.out.println("set");
            }
            c.gridx = i;
            c.gridy = 0;
            header.add(positions[i], c);
        }
            
        frame.add(header, BorderLayout.NORTH);
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        playMove(p);
            
    }
    
    public void playMove(String p) {
        ...
            
        frame.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent keyEvent) {
                System.out.println("Game.keyPressed -- event: " + keyEvent);
                if (keyEvent.getKeyCode() == KeyEvent.VK_RIGHT) {
                    System.out.println("Right key pressed!");
                        
                    int index = searchHeader();
                    System.out.println("index: " + index);
                    if (index != 6) {
                        int shift = index + 1;
                        System.out.println("shift: " + shift);
                        SwingUtilities.updateComponentTreeUI(frame);
                        initialize(p, shift, t);
                    }
                }
            }
    
            @Override
            public void keyReleased(KeyEvent keyEvent) {
                System.out.println("Game.keyReleased -- event: " + keyEvent);
            }
        });
    }
        
    public int searchHeader() {
        for (int i = 0; i < 7; i++) {
            String val = positions[i].getText();
            if (val == "x" || val == "o") {
                System.out.println("i:" + i);
                return i;
            }
        }
        return 0;
    }

我的System.out.println();测试都返回正确的值(数组中正确的索引、移位和数字),但我不确定为什么没有出现:/

如果我的代码需要澄清或遗漏了什么(在听取了我上一篇文章的建议后,我确​​实删除了一些不相关的信息),请告诉我

【问题讨论】:

  • 为了获得更好的帮助,请尽快发布正确的minimal reproducible example 来证明您的问题。我们无法复制粘贴此代码并在我们的计算机中对其进行编译以查看它为什么不起作用。
  • 如果 X 在最右边的 JLabel 中,你按下 JButton 向右移动会发生什么? Key Bindings 比 KeyListener 更适合您想要做的事情。您不必担心 JPanel 有焦点。

标签: java arrays swing


【解决方案1】:

由于您没有提供可以复制到我们的 IDE、运行和调试的最小可运行示例,我想出了这个示例 GUI,它显示 X 向右移动。

我使用右箭头键来执行移位。

这是启动应用程序时的 GUI。

这是移动 X 三个位置后的 GUI。

这是移动 X 四个位置后的 GUI。

Oracle 有一个有用的教程,Creating a GUI With Swing。跳过 Netbeans 部分。

我做的第一件事是通过调用SwingUtilities invokeLater 方法来启动Swing 应用程序。此方法确保在Event Dispatch Thread 上创建和执行 Swing 组件。

接下来,我创建了一个JFrameJFrame 方法必须按特定顺序调用。这是我用于 Swing 应用程序的顺序。

我创建了一个主 JPanel 来保存八个 JLabels 的数组。我还创建了一个 int 来保存 X 的位置。我使用FlowLayout 来布置JLabels 的数组。我(使用 Box 类在JLabels 之间放置一些空格。

当您创建更复杂的游戏时,请使用普通的 Java getter/setter 类创建应用程序模型。

我使用键绑定将右箭头键绑定到Action 类。我使用了AbstractAction,所以我只需要编写actionPerformed 方法。

这是完整的可运行代码。

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class ShiftRightExample implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new ShiftRightExample());
    }
    
    private int position;
    
    private JLabel[] spotLabel;
    
    public ShiftRightExample() {
        this.position = 0;
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Shift Right Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        JPanel mainPanel = createMainPanel();
        frame.add(mainPanel, BorderLayout.CENTER);
        setKeyBindings(mainPanel);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createMainPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        this.spotLabel = new JLabel[8];
        for (int index = 0; index < spotLabel.length; index++) {
            spotLabel[index] = new JLabel(" ");
            panel.add(spotLabel[index]);
            if (index < (spotLabel.length - 1)) {
                panel.add(Box.createHorizontalStrut(20));
            }
        }
        
        updateMainPanel(position, "X");
        
        return panel;
    }
    
    private void setKeyBindings(JPanel panel) {
        panel.getInputMap().put(
                KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "shiftRight");
        panel.getActionMap().put("shiftRight", new ShiftRightAction());
    }
    
    public void updateMainPanel(int position, String value) {
        spotLabel[position].setText(value);
    }
    
    public class ShiftRightAction extends AbstractAction {

        private static final long serialVersionUID = 1L;

        @Override
        public void actionPerformed(ActionEvent event) {
            updateMainPanel(position, " ");
            position++;
            position = position % spotLabel.length;
            updateMainPanel(position, "X");
        }
        
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-26
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多