Java 在JTextArea换行和JScrollPane之间切换

Java 在JTextArea换行和JScrollPane之间切换,java,swing,jscrollpane,jtextarea,Java,Swing,Jscrollpane,Jtextarea,我有一个JCheckBoxMenuItem,我试图使它成为这样,当您单击它时,一个JScrollPane从JPanel中删除,然后一个JTextArea添加了一个换行符,反之亦然,但当我使用它时,代码不起作用 我将滚动窗格/文本区域直接添加到JFrame import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; import javax.swing.JScrollP

我有一个
JCheckBoxMenuItem
,我试图使它成为这样,当您单击它时,一个
JScrollPane
JPanel
中删除,然后一个
JTextArea
添加了一个换行符,反之亦然,但当我使用它时,代码不起作用

我将滚动窗格/文本区域直接添加到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

    }
}

我不确定我是否理解整个问题,或者你最终想要实现什么,但是,让我们看看你必须从哪些问题开始

首先,创建一个
JScrollPane
,它包装了一个
JTextArea

JScrollPane scroll = new JScrollPane(ta);
好的,这很好

接下来,使用
keylister
(从未在代码段中注册),可以将
JScrollPane
JTextArea
添加到屏幕中

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();
    }
}
这实际上有三个问题

  • 将组件添加到容器时,首先会将其从以前的父级移除,在这种情况下,将
    JTextArea
    添加到框架时,会将其从
    JScrollPane
    中移除,但不会重新应用它,因此下次添加时,
    JScrollPane
    将为空
  • 像这样动态更新UI时,需要调用
    revalidate
    ,然后调用
    repaint
    ,以确保布局得到更新
  • KeyListener
    因不工作而臭名昭著,这是因为它注册的组件必须是可聚焦的,并且在触发之前必须具有焦点,更好的解决方案是使用
  • 但如何修复呢?通常,在组件/视图之间切换时,我建议使用
    CardLayout
    ,但老实说,我不确定您为什么要删除
    JScrollPane
    ,因此,我只是将其设置为通过控制键更改
    lineWrap
    状态


    你为什么不使用一种新的方法呢?一个面板上有你的
    JScrollPane
    ,然后另一个面板上有你的
    JTextArea
    ,点击时更换卡片?例如,你可以看到并得出这样的结论。请发表文章,这样我们可以帮助解决这个问题。如果你要编辑这个问题,请像@Leet Falcon建议的MCVE那样进行有用的编辑,而不是替换一个不合逻辑的
    }
    。我有很多代码,如果没有其他部分就无法工作。请尝试制作一个新的简单项目,一个可运行的示例(参见@Leet Falcon提供的链接)“这些部分对这种情况来说并不重要。。“这些正是要从MCVE上拆下的部件。请注意,有一个密切的原因可以归结为“缺乏MCVE”,如果你想让人们更仔细地研究这个问题,请发布MCVE。但要快一点,在投票结束之前只需要再投三票,这样就很难重新提出问题。
    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());
                    }
                });
            }
    
        }
    
    }