【问题标题】:JButton over JScrollPaneJScrollPane 上的 JButton
【发布时间】:2020-09-01 08:50:39
【问题描述】:

我有这样一段代码,应该在JTextArea 上添加按钮放在JScrollPane 中。按钮不在滚动窗格内!

    JScrollPane scrollPane = new JScrollPane();
    scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    scrollPane.setBounds(10, 340, 375, 242);
    contentPane.add(scrollPane);

    JButton btnClean = new JButton();
    btnClean.setBounds(340, 341, 26, 23);
    contentPane.add(btnClean);

    taLog = new JTextArea();
    taLog.setEditable(false);
    taLog.setLineWrap(true);
    taLog.setFont(new Font("Arial", Font.PLAIN, 12));
    scrollPane.setViewportView(taLog);

    epInfo = new JEditorPane();
    epInfo.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
    epInfo.setFont(new Font("Tahoma", Font.PLAIN, 12));
    epInfo.setContentType("text/html");
    epInfo.setEditable(false);
    epInfo.setBackground(null);
    epInfo.setBorder(null);
    epInfo.setBounds(10, 241, 375, 37);
    setInfoText();
    contentPane.add(epInfo);

问题是每当JTextArea 更改其值时,按钮都不会刷新 - 它只是消失了 - 直到我将鼠标光标拖到它上面。我想随后会启动一些repaint()
我发现我可以将DocumentListener 添加到JTextArea 并手动刷新按钮,但它可以工作,直到滚动条出现在JScrollPane 中。 我也可以用

scrollPane.getViewport().addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e)
{}});

但它被多次调用,所有这些刷新都不是必需的。 是否有任何合理(有效)的方法来检查JScrollPane 是否更改?

【问题讨论】:

  • 不要使用空布局。不要使用 setBounds()。 Swing 旨在与布局管理器一起使用。我无法建议使用哪个布局管理器,因为我不了解您想要的布局。发布图片或使用 ascii 艺术来展示您想要的布局。
  • @camickr Null 布局在这种情况下很有用,因为主窗口是固定的。我也在 E​​clipse 中使用 WindowBuilder,然后我不手动放置 XY。我添加了图片。按钮在红色圆圈中。

标签: java swing jbutton jscrollpane


【解决方案1】:

空布局在这种情况下很有用,因为主窗口是固定的

不,没有用。

任何时候您的代码使用随机数(即设置组件的大小/位置)时,代码都不容易维护。

我也使用 WindowBuilder

一个 IDE 生成的代码不能在另一个 IDE 中维护。

学习使用布局管理器。使用布局管理器的目的是避免对数字进行硬编码,并使代码在任何环境下都可维护。

问题是每当 JTextArea 更改其值时,按钮不会刷新

contentPane.add(scrollPane);
...
contentPane.add(btnClean);

Swing 被设计为在添加到同一个容器时以二维显示组件。

如果您希望组件在二维中显示,那么您需要有父/子关系:

- content pane
    - text area
        button

所以代码应该是这样的:

textArea.setLayout( new FlowLayout(FlowLayout.RIGHT) );
//contentPane.add(btnClean);
textArea.add(btnClean);

注意:您可以配置 FlowLayout 以去除顶部和右侧的间距。

这样做的问题是按钮会覆盖文本区域中显示的所有文本。

所以更好的解决方案是让按钮在文本区域之外。

【讨论】:

  • 关于空布局:是的,它很有用。我的意思不是作为这个特定问题的解决方案,而是在一般情况下。坐标不是随机的——我不明白你为什么这么说。我不在乎它在另一个 IDE 中是否可维护(但实际上它是绝对可维护的,因为 WindowBuilder 生成与例如 NetBeans 相矛盾的纯 Java 代码)。请理解我知道其他类型的布局(当然不是全部),我想使用 null 之一。无论如何,这不是主要主题。将按钮添加到文本区域不是解决方案,因为它将与整个字段一起滚动。
  • 我不明白你为什么这么说 - 这就是问题所在。您不了解 Swing 是如何设计的,以及布局管理器如何使代码的维护更容易。例如,如果标签的文本发生变化,标签的大小也会发生变化。如果你想要不同的字体大小怎么办?然后需要更改所有组件的大小和位置。当您使用空布局时,滚动将不起作用。 无论如何,这不是主要主题 - 是的,这是一个问题,因为我们一直在回答与空布局引起的问题相关的问题。正确使用 Swing!
  • 它将与整个字段一起滚动 - 也许您可以使用OverlayLayout。我从未尝试过这样的事情,但它旨在允许多个组件相互叠加显示。如果不是,就像我说的那样,更好的解决方案是让按钮在文本区域之外,这就是 UI 通常的设计方式。
  • 请不要再谈论空布局了。我知道你提到的所有问题,我同意你的看法。我也理解层的含义。问题是你不明白我想要 contentPane 中的空布局,无论 Swing 是如何设计的,并且同意你的所有限制点。也有可能我们谈论两个不同的事情,如果我不手动设置它,你试图告诉我 scrollPane 从它的父级继承布局类型 contentPane?那么它确实可能是一个问题。我会试试 OverlayLayout。
  • 或者,也许您尝试将我的注意力指向与其他布局不同(不是处理?)的事实 null 布局句柄覆盖?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-12
  • 1970-01-01
  • 2012-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多