【问题标题】:Cannot edit JTextField in popup JFrame无法在弹出 JFrame 中编辑 JTextField
【发布时间】:2013-01-26 02:18:27
【问题描述】:

好的,我在弹出 JFrame 中的文本字段有问题... 我实际上有两个独立的程序,一个是游戏,一个是地图编辑器。我决定让游戏有一种内置的地图编辑器,所以我将地图编辑器中的类添加到我游戏项目中的一个新包中,进行了一些小调整(比如从地图编辑器中删除 main() 方法),然后开始工作。地图编辑器作为一个新的 JFrame 弹出,当我单击“新建”按钮时,它会打开一个新的 JFrame,其中包含几个 TextField 和一个请求新地图宽度和高度的按钮。我无法编辑文本字段中的值...而且我不知道为什么... 弹出代码:

private class newMap extends JFrame implements ActionListener{
    JLabel wlbl = new JLabel("Map width: ");
    JTextField w = new JTextField("12");
    JLabel hlbl = new JLabel("Map height: ");
    JTextField h = new JTextField("8");
    JButton create = new JButton("Create map");
    public newMap(Component p){
        super("New Map");
        setSize(100,75);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setResizable(false);
        setLayout(null);
        setVisible(true);
        int bw = 96, bh = 24, s = 4, x = s;

        wlbl.setBounds(x,s,bw,bh);
        x+=s+bw;
        add(wlbl);
        w.setBounds(x,s,bw,bh);
        x+=s+bw;
        add(w);
        hlbl.setBounds(x,s,bw,bh);
        x+=s+bw;
        add(hlbl);
        h.setBounds(x,s,bw,bh);
        x+=s+bw;
        add(h);
        create.setBounds(x,s,bw,bh);
        x+=s+bw;
        create.addActionListener(this);
        add(create);

        setSize(getWidth()-this.getContentPane().getWidth()+x,
                getHeight()-this.getContentPane().getHeight()+s+s+bh);
        setLocationRelativeTo(p);
    }
    public void actionPerformed(ActionEvent e){
        try{
            mapBox.create(Integer.parseInt(w.getText()),Integer.parseInt(h.getText()));
        }catch(NumberFormatException ex){
            return;
        }
        dispose();
    }
}

我显然已经尝试过 w.requestFocusInWidnow() 和 w.requestFocus() 之类的方法,对于框架和我在网上找到的其他一些解决方案也是如此,但没有一个对我有用。

问题已解决: 在解释了我的问题后,我意识到问题必须出现在游戏的代码中,可能在 JFrame 的类中,我注意到我做了一些奇怪的事情,而不是使用 KeyListener 实现来处理输入。(我以前是试图将游戏创建为 JApplet,但我在 JApplet 上遇到了 Keylisteners 的问题)。我将我的 Main 类设为 KeyEventDispatcher 或类似的东西。感谢大家的帮助,这是一个愚蠢的问题(我只是在错误的地方寻找解决方案)。

因此,KeyEventDispatcher 没有正确地将关键操作“分派”给其他组件。 我只是回到了传统的 KeyListener,因为它在 JFrame 中对我来说很好。

【问题讨论】:

标签: java swing popup jframe jtextfield


【解决方案1】:

我怀疑问题在于您如何调用这个新窗口,也许您有一个无限循环或其他一些结构会冻结 Swing 事件调度线程或 EDT,从而使您的 GUI 无响应。如果您能创建并发布一个SSCCE 供我们编译、测试、运行以及可能的修改和更正,我们会非常清楚。

在我看来,您的代码还有其他重要但与您的主要问题无关的问题:

  • 不应在应使用 JOptionPanes 或 JDialogs 等对话框的地方使用 JFrame。
  • 应避免使用绝对定位,而应使用布局管理器。
  • 您应该努力创建符合 Java 命名标准的代码,包括以大写字母开头的类名称。当要求他人阅读和理解您的代码并为您提供帮助时,这一点变得尤为重要。

例如一些快速制作的示例代码:

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

@SuppressWarnings("serial")
public class TestNewMap extends JPanel {
   private MapBox mapBox = new MapBox();
   private NewMap newMap = new NewMap(this);
   private HoverNewMap hoverNewMap = new HoverNewMap();

   public TestNewMap() {
      JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 0));

      btnPanel.add(new JButton(new AbstractAction("Show Your NewMap") {

         @Override
         public void actionPerformed(ActionEvent evt) {
            newMap.setVisible(true);
         }
      }));
      btnPanel.add(new JButton(new AbstractAction("Show Hover's NewMap") {

         @Override
         public void actionPerformed(ActionEvent evt) {
            hoverNewMap.setMapWidth(mapBox.getWidthValue());
            hoverNewMap.setMapHeight(mapBox.getHeightValue());

            Object[] options = { "Create Map", "Cancel" };
            Object initialValue = options[0];
            int result = JOptionPane.showOptionDialog(TestNewMap.this,
                  hoverNewMap, "Get Map Dimensions",
                  JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null,
                  options, initialValue);
            if (result == 0) {
               try {
                  int w = hoverNewMap.getMapWidth();
                  int h = hoverNewMap.getMapHeight();

                  mapBox.create(w, h);
               } catch (NumberFormatException e) {
                  JOptionPane.showMessageDialog(TestNewMap.this,
                        "Please only enter int values", "Non-int Input Error",
                        JOptionPane.ERROR_MESSAGE);
                  hoverNewMap.setMapHeight(0);
                  hoverNewMap.setMapWidth(0);
               }
            }
         }
      }));

      int borderGap = 5;
      setBorder(BorderFactory.createEmptyBorder(borderGap, borderGap,
            borderGap, borderGap));
      setLayout(new BorderLayout(borderGap, borderGap));
      add(btnPanel, BorderLayout.NORTH);
      add(mapBox, BorderLayout.CENTER);
   }

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

      JFrame frame = new JFrame("TestNewMap");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

   private class MapBox extends JPanel {
      private static final int INIT_WIDTH = 12;
      private static final int INIT_HEIGHT = 8;
      private JTextField widthField = new JTextField(
            String.valueOf(INIT_WIDTH), 5);
      private JTextField heightField = new JTextField(
            String.valueOf(INIT_HEIGHT), 5);

      public MapBox() {
         add(new JLabel("Width:"));
         add(widthField);
         add(Box.createHorizontalStrut(10));
         add(new JLabel("Height:"));
         add(heightField);
      }

      public void create(int width, int height) {
         widthField.setText(String.valueOf(width));
         heightField.setText(String.valueOf(height));
      }

      public int getWidthValue() {
         return Integer.parseInt(widthField.getText());
      }

      public int getHeightValue() {
         return Integer.parseInt(heightField.getText());
      }

   }

   private class HoverNewMap extends JPanel {
      private JTextField mapWidth = new JTextField(5);
      private JTextField mapHeight = new JTextField(5);

      public HoverNewMap() {
         add(new JLabel("Width:"));
         add(mapWidth);
         add(Box.createHorizontalStrut(15));
         add(new JLabel("Height:"));
         add(mapHeight);

         setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
      }

      public void setMapWidth(int w) {
         mapWidth.setText(String.valueOf(w));
      }

      public void setMapHeight(int h) {
         mapHeight.setText(String.valueOf(h));
      }

      public int getMapWidth() throws NumberFormatException {
         int w = Integer.parseInt(mapWidth.getText());
         return w;
      }

      public int getMapHeight() throws NumberFormatException {
         int h = Integer.parseInt(mapHeight.getText());
         return h;
      }
   }

   private class NewMap extends JFrame implements ActionListener {
      JLabel wlbl = new JLabel("Map width: ");
      JTextField w = new JTextField("12");
      JLabel hlbl = new JLabel("Map height: ");
      JTextField h = new JTextField("8");
      JButton create = new JButton("Create map");

      public NewMap(Component p) {
         super("New Map");
         setSize(100, 75);
         setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
         setResizable(false);
         setLayout(null);
         // setVisible(true);
         int bw = 96, bh = 24, s = 4, x = s;

         wlbl.setBounds(x, s, bw, bh);
         x += s + bw;
         add(wlbl);
         w.setBounds(x, s, bw, bh);
         x += s + bw;
         add(w);
         hlbl.setBounds(x, s, bw, bh);
         x += s + bw;
         add(hlbl);
         h.setBounds(x, s, bw, bh);
         x += s + bw;
         add(h);
         create.setBounds(x, s, bw, bh);
         x += s + bw;
         create.addActionListener(this);
         add(create);

         setSize(getWidth() - this.getContentPane().getWidth() + x, getHeight()
               - this.getContentPane().getHeight() + s + s + bh);
         setLocationRelativeTo(p);
      }

      public void actionPerformed(ActionEvent e) {
         try {
            mapBox.create(Integer.parseInt(w.getText()),
                  Integer.parseInt(h.getText()));
         } catch (NumberFormatException ex) {
            return;
         }
         dispose();
      }
   }
}

【讨论】:

  • 我偏爱自己做事,我不太喜欢使用布局或 JFrame 子类,但如果需要,我可以将其更改为类似的东西。就 SSCCE 而言,我完全会这样做,除了减少它时我没有问题。例如,如果我复制地图编辑器的所有代码,将其粘贴到新项目中,然后简单地添加一个启动第一个 JFrame 的 main 方法,那么我没有问题。
  • @user1828361:使用布局管理器不会阻止您自己做事,而是更容易维护和更新您的代码。至于减少它时没有问题,那么在我看来,这就是您的主要任务-尝试通过减少代码来隔离错误,直到错误消失。至于不喜欢继承 JFrame ——但这就是你在上面所做的,所以你的陈述让我感到困惑。
  • 嗯,我想通了,将其编辑到问题中,是的,我确实需要隔离问题...
  • @user1828361:你能在显示窗口的地方显示代码吗?
  • 我隔离了问题并修复了它,如果您想了解问题所在,请阅读问题的编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多