java - 滚动条未出现在自定义面板上

标签 java swing scrollbar

我创建了一个扩展JPanel的类RefreshablePanel

public class RefreshablePanel extends JPanel {

static String description="";
static int x=10;
static int y=11;
    
protected void paintComponent(Graphics g){
       super.paintComponent(g);
    for (String line : description.split("\n"))
        g.drawString(line, x, y += g.getFontMetrics().getHeight());
}
void updateDescription(String dataToAppend){
        description = description.concat("\n").concat(dataToAppend);
        System.out.println("The description is "+description);
   }   
}

然后我将它添加到我的 GUI_class 中,如下所示

JScrollPane scrollPane_2 = new JScrollPane();
scrollPane_2.setBounds(32, 603, 889, 90);
frmToolToMigrate.getContentPane().add(scrollPane_2);

descriptionPanel = new RefreshablePanel();
scrollPane_2.setViewportView(descriptionPanel);
descriptionPanel.setBackground(Color.WHITE);
descriptionPanel.setLayout(null);
    

我已经在类中添加了滚动条,我正在其中创建 RefreshablePanel 实例,但滚动条没有出现。 我尝试过添加

@Override
public Dimension getPreferredSize() {
    return new Dimension(400, 1010);
}

到可刷新面板,但随后字符串像这样消失 enter image description here

当我向下滚动时什么也没有出现

最佳答案

  1. 您使用的是 null 布局,因此一切都无法正常工作。 Swing 的核心设计是为了利用布局管理器。

  2. 您的RefreshablePanel没有可辨别的大小,这意味着当您添加到滚动 Pane 时,滚动 Pane 可能只是认为它的大小应该0x0RefreshablePanel 需要向滚动 Pane 提供某种大小提示,最好通过 getPreferredSize 方法

  3. 您可以使用 JLabel(文本封装在 html 中)或不可编辑的 JTextArea 来实现相同的结果

已更新

快速检查您的代码。您将 xy 值声明为 static,并递增 中的 y 值PaintComponent 方法

static int x=10;
static int y=11;

protected void paintComponent(Graphics g){
   super.paintComponent(g);
    for (String line : description.split("\n"))
        g.drawString(line, x, y += g.getFontMetrics().getHeight());
}

这意味着两件事。

  1. 如果您有多个 RefreshablePanel 实例,它们将共享相同的 x/y 值并更新它们
  2. y 不断更新到新位置,因此如果面板被绘制两次,在第二次绘制时,y 位置将从原来的位置开始最后一次调用退出时。

请记住,您无法控制绘制过程。绘制周期可以在系统决定需要的任何时间执行...

x/y 值设置为 paintComponent 方法的局部变量...

已更新

如果可用空间允许,滚动 Pane 将尝试匹配组件的首选大小。这可能意味着滚动条可能不会出现,直到您调整窗口大小...但您使用的是 null 布局,因此这对您不起作用...

要影响滚动 Pane 的大小,您可以使用 Scrollable 界面...

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Scrollable01 {

    public static void main(String[] args) {
        new Scrollable01();
    }

    public Scrollable01() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                RefreshablePanel pane = new RefreshablePanel();
                pane.updateDescription("1. You're using null layouts, so nothing is going to work the way it should. Swing is designed at the core to utilise layout managers.");
                pane.updateDescription("2. You're RefreshablePanel has no discernible size, meaning that when you add to the scroll pane, the scroll pane is likely to simply think it's size should 0x0. RefreshablePanel needs to provide some kind of size hint back to the scrollpane, preferably via the getPreferredSize method");
                pane.updateDescription("3. You could use a JLabel (with text wrapped in html) or a non-editable JTextArea to achieve the same results");

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(pane));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class RefreshablePanel extends JPanel implements Scrollable {

        public String description = "";

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 1010);
        }

        @Override
        protected void paintComponent(Graphics g) {
            int x = 10;
            int y = 11;
            super.paintComponent(g);
            for (String line : description.split("\n")) {
                g.drawString(line, x, y += g.getFontMetrics().getHeight());
            }
        }

        void updateDescription(String dataToAppend) {
            description = description.concat("\n").concat(dataToAppend);
            System.out.println("The description is " + description);
            repaint();
        }

        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return new Dimension(400, 400);
        }

        @Override
        public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 64;
        }

        @Override
        public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 64;
        }

        @Override
        public boolean getScrollableTracksViewportWidth() {
            return false;
        }

        @Override
        public boolean getScrollableTracksViewportHeight() {
            return false;
        }
    }
}

关于java - 滚动条未出现在自定义面板上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19150713/

相关文章:

html - Canvas 滚动条不起作用

用于识别 Solr 服务器是在云模式还是独立模式下运行的 Java 代码

java - 参数索引超出范围(0 < 1)进入spring jdbctemplate

jquery - 如何在使用子元素滚动条时禁用可拖动的div

java - 网 bean : how to resize the UI Window to screen Size

java - 从一种形式过渡到另一种形式的正确方法是什么?

html - 滚动条向下移动页面

Java MapReduce 按日期计数

java - 使用 File 和 FileInputStream 与 Mockito/PowerMockito 测试类

java - 更改框架字体以及框架中所有组件的字体