滚动条未显示在自定义面板上

时间:2013-10-03 04:21:44

标签: java swing scrollbar

我创建了一个扩展RefreshablePanel

的课程JPanel
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);
}

到可刷新的Panel但是字符串就像这样消失了 enter image description here

当我向下滚动时没有出现

1 个答案:

答案 0 :(得分:3)

  1. 您正在使用null布局,因此任何事情都无法正常运行。 Swing的核心是利用布局管理器。

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

  3. 您可以使用JLabel(包含html的文字)或不可编辑的JTextArea来获得相同的结果

  4. <强>更新

    快速检查您的代码。您要将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位置将从第一次调用时的最后位置开始退出。
    3. 请记住,您无法控制绘画过程。可以在系统决定需要的任何时间执行绘制周期......

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

      <强>更新

      如果可用空间允许,滚动窗格将尝试匹配组件的首选大小。这可能意味着在您调整窗口大小之前可能不会显示滚动条...但您使用的是null布局,因此对您无效...

      要影响滚动窗格的大小,可以使用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;
              }
          }
      }