在JTextArea自动换行和JScrollPane之间切换

时间:2016-01-11 14:58:18

标签: java swing jscrollpane jtextarea

我有一个JCheckBoxMenuItem,我尝试这样做,以便点击它时JScrollPaneJPanel中删除,然后添加JTextArea自动换行,反之亦然,但是当我使用它时,代码不起作用

我将scrollpane / textArea直接添加到JFrame

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class Builder extends JFrame implements KeyListener{
    private static final long serialVersionUID = 1156397512984837248L;

    JTextArea ta = new JTextArea(30,50);
    JScrollPane scroll = new JScrollPane(ta);
    boolean s = false;

    public test(){
        setTitle("Builder");
        setSize(600,600);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setResizable(false);
        setVisible(true);
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_CONTROL){
            if(s == false){
                s = true;
                remove(scroll);
                ta.setLineWrap(true);
                add(ta);
                repaint();
            }else{
                s = false;
                ta.setLineWrap(false);
                remove(ta);
                add(scroll);
                repaint();
            }
        }

    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }
}

1 个答案:

答案 0 :(得分:1)

我不确定我是否了解整个问题或者您最终想要达到的目标,但是,让我们来看看您必须从一开始就遇到的一些问题......

首先,您创建一个包裹JScrollPane ...

JTextArea
JScrollPane scroll = new JScrollPane(ta);

好的,这很好。

接下来,使用KeyListener(从未在您的代码段中注册),您可以将JScrollPaneJTextArea添加到屏幕

if(e.getKeyCode() == KeyEvent.VK_CONTROL){
    if(s == false){
        s = true;
        remove(scroll);
        ta.setLineWrap(true);
        add(ta);
        repaint();
    }else{
        s = false;
        ta.setLineWrap(false);
        remove(ta);
        add(scroll);
        repaint();
    }
}

这实际上有三个问题......

  1. 向容器添加组件时,首先将其从其上一个父项中删除,在这种情况下,当您将JTextArea添加到框架时,将其从JScrollPane中删除,但是永远不要重新申请,因此下次添加时JScrollPane将为空
  2. 像这样动态更新UI时,您需要调用revalidate后跟repaint以确保布局更新
  3. KeyListener因不工作而臭名昭着,这是因为它注册的组件必须是可聚焦的并且在它触发之前具有焦点,更好的解决方案是使用{{3 }}
  4. 但是如何解决呢?通常,在组件/视图之间切换时,我建议使用CardLayout,但说实话,我不确定您为什么要删除JScrollPane,所以我只是设置了它可以通过 Control 键更改lineWrap状态

    Key Bindings API

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.awt.event.ActionEvent;
    import java.awt.event.KeyEvent;
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;
    import javax.swing.AbstractAction;
    import javax.swing.ActionMap;
    import javax.swing.InputMap;
    import static javax.swing.JComponent.WHEN_IN_FOCUSED_WINDOW;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.KeyStroke;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class Switcher {
    
        public static void main(String[] args) {
            new Switcher();
        }
    
        public Switcher() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private JTextArea ta;
    
            public TestPane() {
                setLayout(new BorderLayout());
                ta = new JTextArea(10, 20);
                ta.setLineWrap(true);
                add(new JScrollPane(ta));
    
                try (Reader r = new FileReader(new File("Labyrinth.txt"))) {
                    ta.read(r, "Labyrinth");
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
    
                InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
                ActionMap actionMap = getActionMap();
    
                inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL, KeyEvent.CTRL_DOWN_MASK), "pressed.control");
                actionMap.put("pressed.control", new AbstractAction() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        ta.setLineWrap(!ta.getLineWrap());
                    }
                });
            }
    
        }
    
    }