java - JScrollPane 的奇怪问题 - 尽管使用了 : setVerticalScrollBarPolicy(JScrollPane. VERTICAL_SCROLLBAR_​​ALWAYS,但滚动条未显示;

标签 java swing scrollbar

所以,在下面的代码中,我在左侧有一个 JTextArea。右上角的 JScrollPane 看起来不错。使用相同的代码,我还在右下侧添加了一个 JScrollPane,但是尽管代码相同,但保存了首选大小和绝对定位,垂直滚动条似乎没有显示。

我将在代码后添加 GUI 的屏幕截图。预先感谢您为解决此问题提供的任何帮助。

    frame = new JFrame("Title");
    frame.setLayout(null);
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.getContentPane().setPreferredSize(new Dimension(width, height));      
    frame.pack();

    Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
    frame.setLocation(dim.width/2-frame.getSize().width/2, dim.height/2-frame.getSize().height/2);
    frame.setResizable(false);
    frame.addKeyListener(this);

    //scroll and text area
        textArea = new JTextArea();
        textArea.setText("Static Text\n");
        textArea.setFont(new Font("Consolas", 0, 12));      
        textArea.setColumns(50);
        textArea.setLineWrap(true);
        textArea.setEditable(false);
        scrollPane = new JScrollPane(textArea);
        scrollPane.setPreferredSize(new Dimension(width/2, height * 4 / 5));
        scrollPane.setBounds(width/2, 0, width/2, height * 4 / 5);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        frame.add(scrollPane);
        inputTextArea = new JTextArea();
        inputTextArea.setText(">");
        inputTextArea.setFont(new Font("Consolas", 0, 12));     
        inputTextArea.setColumns(50);
        inputTextArea.setLineWrap(true);
        inputScrollPane = new JScrollPane(inputTextArea);
        inputScrollPane.setPreferredSize(new Dimension(width/2, height / 5));               
        inputScrollPane.setBounds(width/2, height * 4 / 5, width, height);
        inputScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        frame.add(inputScrollPane);
    //map
        mapView = new JTextArea();
        mapView.setFont(new Font("Consolas", 0, 8));        
        mapView.setEditable(false);
        mapView.setPreferredSize(new Dimension(width/2, height));
        mapView.setText(state.getCurrentMap().toString());
        mapView.addKeyListener(this);
        mapView.setBounds(0, 0, width/2, height);
        frame.add(mapView);

    frame.pack();
    frame.setVisible(true);

As you can see, the lower right JScrollPane is missing the vertical scroll bar

最佳答案

该代码存在几个重大问题,包括

  • 使用空布局。虽然 null 布局和 setBounds() 对于 Swing 新手来说似乎是创建复杂 GUI 的最简单、最好的方法,但创建的 Swing GUI 越多,使用它们时遇到的困难就越严重。当 GUI 调整大小时,它们不会调整组件的大小,它们是增强或维护的皇家女巫,放置在滚动 Pane 中时它们完全失败,在所有平台或与原始分辨率不同的屏幕分辨率上查看时,它们看起来非常糟糕。相信我,这会让你的调试工作变得更加困难。因此,您最好学习并使用布局管理器。您可以在这里找到布局管理器教程:Layout Manager Tutorial ,您可以在此处找到 Swing 教程和其他 Swing 资源的链接:Swing Info .
  • 您正在设置 JTextArea 的大小/边界。这会阻止它们在添加文本时适当扩展,并且会阻止出现周围 JScrollBar 的滚动条。请改为设置 JTextArea 列和行属性。
  • 向文本组件添加 KeyListener。虽然这不会导致您当前的错误,但应该避免这种情况,并且通常会扰乱组件的功能。最好使用更高级别的监听器,例如 DocumentListener 或 DocumentFilter。

例如,下面的代码展示了如何使用简单的布局、文本区域列和行属性,以及如何使用键绑定(bind)来捕获用户按下 Enter 键(如果需要):

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;

@SuppressWarnings("serial")
public class LayoutExample extends JPanel {
    private static final int MV_ROWS = 65;
    private static final int MV_COLS = 100;
    private static final int TA_ROWS = 34;
    private static final int TA_COLS = 54;
    private static final int ITA_ROWS = 8;
    private static final Font MV_FONT = new Font("Consolas", 0, 8);
    private static final Font TA_FONT = new Font("Consolas", 0, 12);

    private JTextArea mapView = new JTextArea(MV_ROWS, MV_COLS);
    private JTextArea textArea = new JTextArea("Static Text\n", TA_ROWS, TA_COLS);
    private JTextArea inputTextArea = new JTextArea(ITA_ROWS, TA_COLS);

    public LayoutExample() {
        mapView.setFont(MV_FONT);
        mapView.setEditable(false);
        mapView.setFocusable(false);
        JScrollPane mvScrollPane = new JScrollPane(mapView);

        textArea.setFont(TA_FONT);
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        textArea.setEditable(false);
        textArea.setFocusable(false);
        JScrollPane taScrollPane = new JScrollPane(textArea);
        taScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        setEnterKeyBindings(inputTextArea);
        inputTextArea.setFont(TA_FONT);
        inputTextArea.setLineWrap(true);
        inputTextArea.setWrapStyleWord(true);
        JScrollPane itaScrollPane = new JScrollPane(inputTextArea);
        itaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        JPanel rightPanel = new JPanel(new BorderLayout());
        rightPanel.add(taScrollPane, BorderLayout.CENTER);
        rightPanel.add(itaScrollPane, BorderLayout.PAGE_END);

        setLayout(new GridLayout(1, 0));
        add(mvScrollPane);
        add(rightPanel);

        inputTextArea.setText(">");
    }

    // to capture the "enter" key being pressed without having to use a
    // KeyListener
    private void setEnterKeyBindings(final JTextArea textComponent) {
        // only accept input when this component is focused
        int condition = WHEN_FOCUSED; 
        InputMap inputMap = textComponent.getInputMap(condition);
        ActionMap actionMap = textComponent.getActionMap();

        // only will bind one keystroke -- that for enter key
        KeyStroke enterKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
        inputMap.put(enterKeyStroke, enterKeyStroke.toString());

        // action to take if enter is pressed
        actionMap.put(enterKeyStroke.toString(), new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // get text from input text area, and then clear text
                String text = textComponent.getText();
                textComponent.setText(">");

                // append this text to the upper text area
                textArea.append(text + "\n");

                // TODO: send text elsewhere via chat?
            }
        });
    }

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

        JFrame frame = new JFrame("Title");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

关于java - JScrollPane 的奇怪问题 - 尽管使用了 : setVerticalScrollBarPolicy(JScrollPane. VERTICAL_SCROLLBAR_​​ALWAYS,但滚动条未显示;,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45130364/

相关文章:

html - 向滚动条添加箭头

java - 在某些 Android 设备上获取类未找到异常/noclassdefound 错误

java - PGraphics 内存不足问题 Java/Processing.org

java - 在 JMenuItem 中的 Icon 和 Text 之间插入垂直分隔符

java - 如何为 JComboBox 中的项目分配不同的颜色?

wpf - 是否可以阻止垂直滚动条将 DataGrid 列/标题向左推?

javascript - 在没有滚动条的情况下滚动 div 内容

java - 如何在java中制作像枚举一样的键值

java - 改进的集合迭代器

java - 当调用 TransferHandler canImport 方法时,来自 jvm 外部的可传输数据的传输数据默认为 null 吗?