【问题标题】:Dynamic FlowLayout动态流布局
【发布时间】:2014-11-01 09:16:06
【问题描述】:

我正在尝试制作一个从用户那里获取输入的程序,当用户按下回车键时,我会在我的 FlowLayout 面板中排列按钮的属性。但显然我的代码不起作用。不过没有错误。

package hm2v;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
import javax.swing.border.*;

public class LayoutM extends JFrame {

static String[] alc = {"LEFT", "RIGHT"};

static JLabel align = new JLabel("Aligment ");
static JLabel hgap = new JLabel("HGap ");
static JLabel vgap = new JLabel("VGap ");

final static JComboBox aligncom = new JComboBox(alc);
final static JTextField hgaptext = new JTextField(10);
final static JTextField vgaptext = new JTextField(10);

final static FlowLayout exL = new FlowLayout(FlowLayout.LEFT, 3, 4);

public static void main(String[] args) {

    new LayoutM();

    LayoutM frame = new LayoutM();
    frame.setTitle("Dynamic FlowLayout");
    frame.setSize(400, 325);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

}

public LayoutM() {

    Container contain = getContentPane();
    contain.setLayout(new BorderLayout());

    final FlowLayout exL = new FlowLayout(FlowLayout.LEFT, 3, 4);

    final JPanel panel1 = new JPanel();
    panel1.setLayout(exL);
    panel1.setBorder(new TitledBorder("A Container of FlowLayout"));
    for (int i = 0; i < 15; i++) {
        panel1.add(new JButton("Component " + i));
    }

    JPanel panel2 = new JPanel();
    panel2.setLayout(new BorderLayout());
    panel2.setBorder(new TitledBorder("FlowLayout Properties"));

    JPanel p3 = new JPanel();
    p3.setLayout(new GridLayout(3, 1, 0, 5));

    JPanel p4 = new JPanel();
    p4.setLayout(new GridLayout(3, 1, 0, 5));

    p3.add(align);
    p3.add(hgap);
    p3.add(vgap);

    p4.add(aligncom);
    p4.add(hgaptext);
    p4.add(vgaptext);

    panel2.add(p3, BorderLayout.WEST);
    panel2.add(p4);

    contain.add(panel1);
    contain.add(panel2, BorderLayout.SOUTH);

    addKeyListener(new KeyListener() {
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                System.out.println("Enter pressed");

                aligncom.addItemListener(new ItemListener() {
                    @Override
                    public void itemStateChanged(ItemEvent e) {
                        int x = aligncom.getSelectedIndex();
                        switch (x) {
                            case 0: {
                                exL.setAlignment(FlowLayout.LEFT);
                            }
                            case 1: {
                                exL.setAlignment(FlowLayout.RIGHT);
                                break;
                            }
                        }

                    }

                });

                hgaptext.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        String y = hgaptext.getText();
                        int z = Integer.parseInt(y);

                        exL.setHgap(z);

                    }
                });

                vgaptext.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        String v = vgaptext.getText();
                        int g = Integer.parseInt(v);

                        exL.setHgap(g);

                    }
                });

            }
        }

        @Override
        public void keyTyped(KeyEvent e) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public void keyReleased(KeyEvent e) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }

    });

}
}

当我输入输入并按下回车键时,没有任何变化,并且没有写“按下回车键”。我在哪里做错了?谢谢!

【问题讨论】:

    标签: java swing user-interface keylistener


    【解决方案1】:

    第一个问题

    您正在尝试将 KeyListener 添加到框架中。我不明白你为什么需要这个。据我了解,当用户在输入后按回车键时,应该会发生一些事情。

    您只需在文本字段中添加ActionListener 即可完成此操作。只要该领域仍然有焦点,这将起作用。这就是您想要的方式(使该领域具有焦点)。所以摆脱KeyListener

    第二个问题

    即使 KeyListener 确实 工作,您甚至什么都不做,只是向组件添加一个新的侦听器。所以每次按键时,所发生的只是另一个监听器被添加到组件中......没有别的。

    第三个问题

    在进行任何布局更改后,您需要 revalidaterepaint panel1

     panel1.revalidate();
     panel1.repaint();
    

    结论

    1. 彻底摆脱KeyListener(删除它,并保持其他所有内容不变 - 将代码留在 keypressed 方法中)
    2. ActionListenersItemListener 中重新验证并重新绘制panel1

    这就是让它工作所需的一切

    哦,您在0 案例中缺少break

    case 0: {
       exL.setAlignment(FlowLayout.LEFT);
       break;
    }
    

    更新

    用户选择“左”或“右”,输入HGap和VGap,只有在用户按下回车后,它们才会改变。

    您基本上必须取出我们刚刚处理的所有侦听器,并将键绑定添加到内容窗格。 You can see this post and use the same code。只需将“LEFT”更改为“ENTER”即可。而 doSomethingWhenLeftIsPressed() 方法您应该只从组合框和字段中获取值并设置布局,全部合二为一

    我会在这里发布代码

    JPanel panel = (JPanel)frame.getContentPane();
    InputMap imap = panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
    imap.put(KeyStroke.getKeyStroke("ENTER"), "layoutAction");
    ActionMap amap = panel.getActionMap();
    Action leftAction = new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
            doSomethingWhenEnterIsPressed();
        }
    };
    amap.put("layoutAction", leftAction);
    
    ...
    private void doSomethingWhenEnterIsPressed() {
        // get values from field and combo and set the layout like before
    }
    

    【讨论】:

    • 我也有一个组合框。当用户选择 Left 或 Right 并键入 HGap 和 VGap 时;按下回车键后,组件应该会改变。
    • 它工作得很好,谢谢,但问题是现在我只能安排左或右一次。例如,我选择了向左,他们向左走。然后我试了一下,没有任何改变。
    • 您在case 0 中缺少break
    • 哦,我的错……最后一个问题是它不应该在用户选择左或右后改变对齐方式。用户选择“Left”或“Right”,输入HGap和VGap,只有在用户按下回车后才会改变。
    • 不,不会太久。您基本上必须取出我们刚刚处理的所有侦听器,并将键绑定添加到内容窗格。你可以看到this post and use the same code。只需将"LEFT" 更改为"ENTER"。而doSomethingWhenLeftIsPressed() 方法您应该只从组合框和字段中获取值并设置布局,全部合二为一
    【解决方案2】:

    在新订单后尝试函数revalidate

    【讨论】:

    • 设置我的FlowLayout对齐后,我写panel1.revalidate();那正确吗 ?因为它不起作用。
    猜你喜欢
    • 1970-01-01
    • 2014-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-24
    • 1970-01-01
    • 2014-07-02
    相关资源
    最近更新 更多