首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java终端开发

Java终端开发
EN

Stack Overflow用户
提问于 2014-05-08 23:22:49
回答 1查看 959关注 0票数 0

忍受我吧。我正在制作一个java控制台,类似于在这里找到的DragonConsole https://code.google.com/p/dragonconsole/。一切都按计划进行,但我想实现一个在DragonConsole中找到的特性。我想增加到我的能力,有垂直滚动条延伸到底部的框架,就像它在DC。

这是我的。

正如你所看到的,垂直滚动条没有延伸到底部,而国际海事组织,它看起来不专业。但我仍然是个业余爱好者

下面是我的程序的组织方式:输出是一个jScrollPane,输入是一个简单的jTextField。用户输入输入,并显示结果输出。

现在,我已经查看了DragonConsole的源代码,以及它对我来说是如何工作的复杂的方法。据我所知,有一个用户输入命令的jTextArea,但我不知道垂直滚动条是如何工作的。

有人能帮我模仿一下龙虎队的滚动条吗?

还可以看到,DC上的输入与垂直滚动条一起移动。我怎么也能做到这一点。

输入区域没有地方可以看到..。

"cls“命令调用此函数:

代码语言:javascript
复制
public void clear() {
        console.setText("");
        print(""); // printing will automatically print the '> ' at the beginning
        startIndex = console.getText().length();
    }

打印功能:

代码语言:javascript
复制
public void print(String s) { // prints output to the console
        console.append(System.lineSeparator() + prompt + s);
    }

产生的错误:

代码语言:javascript
复制
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: bad position: 110
    at javax.swing.text.JTextComponent.setCaretPosition(JTextComponent.java:1678)   at javax.swing.text.JTextComponent.setCaretPosition(JTextComponent.java:1678)
    at Main.Terminal.caretUpdate(Terminal.java:198)
    at javax.swing.text.JTextComponent.fireCaretUpdate(JTextComponent.java:407)
    at javax.swing.text.JTextComponent$MutableCaretEvent.fire(JTextComponent.java:4417)
    at javax.swing.text.JTextComponent$MutableCaretEvent.stateChanged(JTextComponent.java:4439)
    at javax.swing.text.DefaultCaret.fireStateChanged(DefaultCaret.java:798)
    at javax.swing.text.DefaultCaret.changeCaretPosition(DefaultCaret.java:1273)
    at javax.swing.text.DefaultCaret.handleSetDot(DefaultCaret.java:1169)
    at javax.swing.text.DefaultCaret.setDot(DefaultCaret.java:1150)
    at javax.swing.text.DefaultCaret$Handler.removeUpdate(DefaultCaret.java:1796)
    at javax.swing.text.AbstractDocument.fireRemoveUpdate(AbstractDocument.java:260)
    at javax.swing.text.AbstractDocument.handleRemove(AbstractDocument.java:623)
    at javax.swing.text.AbstractDocument.remove(AbstractDocument.java:591)
    at javax.swing.text.AbstractDocument.replace(AbstractDocument.java:667)
    at javax.swing.text.JTextComponent.setText(JTextComponent.java:1718)
    at Main.Terminal.doCommand(Terminal.java:218)
    at Main.Terminal.keyPressed(Terminal.java:168)
    at java.awt.Component.processKeyEvent(Component.java:6463)
    at javax.swing.JComponent.processKeyEvent(JComponent.java:2829)
    at java.awt.Component.processEvent(Component.java:6282)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4861)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1895)
    at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:762)
    at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1027)
    at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:899)
    at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:727)
    at java.awt.Component.dispatchEventImpl(Component.java:4731)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Window.dispatchEventImpl(Window.java:2719)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:729)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:688)
    at java.awt.EventQueue$3.run(EventQueue.java:686)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:702)
    at java.awt.EventQueue$4.run(EventQueue.java:700)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:699)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

它似乎指向了一个问题:

代码语言:javascript
复制
@Override
    public void caretUpdate(CaretEvent e) {
        // Ensure that the caret position can only be a valid location
        if (e.getDot() < startIndex) {
            console.setCaretPosition(startIndex);
            Toolkit.getDefaultToolkit().beep();
        }
    }

修正错误的代码

代码语言:javascript
复制
public void clear() {
        startIndex = 0; // set it to zero to prevent error from happening
        console.setText(""); // this will erase anything on screen, but start the input seqence on the next line
    }

再次感谢您的帮助@amurka :)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-09 12:28:37

查看DragonConsole源代码,它支持两种模式:内联模式和不内联模式。首先,滚动条延伸到底部的图片是内联模式下的DragonConsole。

在这种模式下,它只是一个JTextPane,然后添加到一个JScrollPane中。这就是为什么滚动条延伸到底部的原因。然后将KeyListener (keyPressed方法)和CaretListener (caretUpdate函数)添加到JTextPane中。最后,它使用在DocumentFilter类中实现的自定义InputController来获取您看到的控制台行为。

因此,总结如下:

  • 创建JTextPane。看看initializeConsole() in DragonConsole.java
  • CaretListenerKeyListener添加到该文本窗格。看看caretUpdate()keyPressed()中的DragonConsole.java
  • 设置自定义DocumentFilter。查看InputController.java (实际上,在inializeConsole方法中设置文档样式是完成的)。

您这样做的方式实际上与DragonConsole在不采用内联模式时所做的方式相同。在本例中,它使用一个JTextPane作为输出区域,一个JTextArea用于输入区域,并且在滚动条方面应该是相同的。

编辑:下面是一个内联控制台的超级简单示例。

代码语言:javascript
复制
public class Console extends JPanel implements KeyListener, CaretListener {

    private static final String PROMPT = ">>";

    private JScrollPane scrollPane;
    private JTextArea consoleTextPane;

    private int startIndex;

    public Console() {
        super();

        // Create a text area
        consoleTextPane = new JTextArea();
        consoleTextPane.setText(PROMPT);
        consoleTextPane.setBorder(null);
        // Wraps the text if it goes longer than a line, but NOT on word boundary
        // like a normal console
        consoleTextPane.setLineWrap(true);
        consoleTextPane.setWrapStyleWord(false);

        // Set the initial caret position
        startIndex = consoleTextPane.getText().length();
        consoleTextPane.setCaretPosition(startIndex);

        // Add the caret and key listeners
        consoleTextPane.addCaretListener(this);
        consoleTextPane.addKeyListener(this);

        // Scrollbar, always show the vertical one
        scrollPane = new JScrollPane(consoleTextPane);
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.setBorder(null);

        JPanel panelCenter = new JPanel(new BorderLayout());
        panelCenter.setPreferredSize(new Dimension(400, 200));
        panelCenter.add(scrollPane, BorderLayout.CENTER);

        add(panelCenter, BorderLayout.CENTER);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Console");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.add(new Console());
        frame.pack();
        frame.setVisible(true);
    }

    @Override
    public void keyTyped(KeyEvent e) {
        // All processing in keyPressed
    }

    @Override
    public void keyReleased(KeyEvent e) {
        // All processing in keyPressed
    }

    @Override
    public void keyPressed(KeyEvent e) {
        switch(e.getKeyCode()) {
            case KeyEvent.VK_ENTER:
                // ENTER key was pressed
                // Get the "Command"
                String command = consoleTextPane.getText().substring(startIndex);

                if (!command.isEmpty()) {
                    // TODO: do something with the command
                    consoleTextPane.append(System.lineSeparator() 
                            + "Command Entered: " + command);
                }

                // Update the start index and append a new prompt
                consoleTextPane.append(System.lineSeparator() + PROMPT);
                startIndex = consoleTextPane.getText().length();

                // Consume the ENTER key event so further processing is not
                // performed
                e.consume();
                break;
            case KeyEvent.VK_BACK_SPACE:
                // Make sure this is a valid delete
                if (consoleTextPane.getCaretPosition() <= startIndex) {
                    e.consume();
                    Toolkit.getDefaultToolkit().beep();
                }

                break;
            // TODO: add key presses here as desired
            default:
                //System.out.println("Unhandled: " + e.getKeyCode());
                break;
        }
    }

    @Override
    public void caretUpdate(CaretEvent e) {
        // Ensure that the caret position can only be a valid location
        if (e.getDot() < startIndex) {
            consoleTextPane.setCaretPosition(startIndex);
            Toolkit.getDefaultToolkit().beep();
        }
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23554242

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档