【发布时间】:2020-07-13 16:37:49
【问题描述】:
我正在构建一个聊天应用程序,我在其中将聊天添加到附加到 JScrollPane 的 JPanel。可以在我的JPanel 中添加和删除聊天,并且我希望我的JScrollPane 执行 3 个功能
-
如果垂直的
scrollBar不可见(即由于屏幕上的聊天很少而无需滚动),并且当新聊天进入面板导致scrollBar第一次可见时,则@987654328 @ 必须滚动到最大值才能使新添加的聊天可见 -
如果用户已尽可能滚动到
scrollPane的最大值/最底部,并且当新聊天进入面板时导致scrollBar的最大值上升,则执行与操作 1 相同的操作 -
如果用户向上滚动聊天以查看以前的消息(即到某个小于
scrollBar的最大值的随机点),然后出现一些新聊天,则聊天中必须出现滚动按钮,并且如果用户点击它,scrollBar会滚动到 NEW MAXIMUM 值,以使新添加的聊天可见
基本上我的算法如下
//The user is currently at the bottom of the chat or scrollBar is not visible therefore making current & maximum value = 0
if (scrollBar.currentValue() == scrollBar.maxValue()) {
scrollButton.setVisible(false);
guiUpdate(); //Then Add,Remove The Chat
scrollToVeryButton();
}
else {
//The user is somewhere top of the chat looking at previous messages
guiUpdate(); //Then Add,Remove The Chat
scrollButton.setVisible(true); //Upon clicking scrollToVeryButton(); Is Called
}
不幸的是,该算法不起作用,并且无论如何滚动按钮始终可见。这是完整的代码:
用于显示聊天的聊天显示类
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
class ChatDisplay extends JLayeredPane {
private JScrollPane scrollPane;
private JPanel chatDisplay;
private Scroll notify;
ChatDisplay() {
setLayout(null);
addChatDisplay();
addNotifyButton();
}
private void addChatDisplay() {
chatDisplay = new JPanel();
chatDisplay.setLayout(new BoxLayout(chatDisplay, BoxLayout.Y_AXIS));
scrollPane = new JScrollPane(chatDisplay);
scrollPane.setBounds(0, 0, 300, 300);
add(scrollPane, new Integer(0));
}
private void addNotifyButton() {
notify = new Scroll();
notify.setBounds(150, 150, 80, 50);
add(notify, new Integer(1));
notify.setVisible(false);
}
//Called To Add An New Chat
void addButton(String text) {
guiUpdate(() -> {
chatDisplay.add(new Chat(text));
chatDisplay.revalidate();
chatDisplay.repaint();
});
}
//The general update when gui is changed in anyway
private void guiUpdate(Runnable update) {
JScrollBar scrollBar = scrollPane.getVerticalScrollBar();
if (scrollBar.getValue() == scrollBar.getMaximum()) {
notify.setVisible(false);
update.run();
scrollBar.setValue(scrollBar.getMaximum());
} else {
update.run();
notify.setVisible(true);
}
}
//Called To Remove An Chat
private void removeButton(JButton button) {
guiUpdate(() -> {
chatDisplay.remove(button);
chatDisplay.revalidate();
chatDisplay.repaint();
});
}
//The Chat Button
private final class Chat extends JButton implements ActionListener {
private Chat(String text) {
setText(text);
Dimension dim = new Dimension(300, 100);
setPreferredSize(dim);
setMinimumSize(dim);
setMaximumSize(dim);
addActionListener(Chat.this);
}
@Override
public void actionPerformed(ActionEvent e) {
removeButton(Chat.this); //Upon Clicking Remove Itself From Chat
}
}
// The ScrollBar
private final class Scroll extends JButton implements ActionListener {
private Scroll() {
setText("Scroll");
setBackground(Color.green);
addActionListener(Scroll.this);
}
@Override
public void actionPerformed(ActionEvent e) {
JScrollBar scrollBar = scrollPane.getVerticalScrollBar();
scrollBar.setValue(scrollBar.getMaximum()); //Scroll To The Bottom Upon Clicking
setVisible(false); //Its Job Is Done Wait For Next Event
}
}
}
ChatPanel 设置为内容窗格
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
class ChatPanel extends JPanel implements ActionListener {
private ChatDisplay display;
private int chat;
ChatPanel() {
super(null);
addDisplay();
addButton();
}
private void addDisplay() {
display = new ChatDisplay();
display.setBounds(0, 0, 300, 300);
add(display);
}
private void addButton() {
JButton add = new JButton("ADD CHAT");
add.addActionListener(this);
add.setBounds(0, 310, 300, 30);
add(add);
}
@Override
public void actionPerformed(ActionEvent e) {
display.addButton("Chat " + (++chat));
}
}
主类
import javax.swing.JFrame;
public class Main {
public static void main(String args[]) throws Exception {
JFrame frame = new JFrame("Design Frame");
frame.setContentPane(new ChatPanel());
frame.setSize(320, 380);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setVisible(true);
}
}
【问题讨论】:
-
为了更好的帮助,请尽快发布正确的minimal reproducible example,与缩进保持一致,对于 4 个空格的 Java,单个空格几乎不可能跟随程序的流程(并且无需在程序的每一行之间有 1 个空行,它使程序比它应该的更长并且更难阅读)。
.setLayout(null)某事告诉我那里出了点问题,尤其是JScrollPanes。 -
我已经在这里发布了整个代码并且我使用空布局管理器只是为了演示目的。布局管理器仍然存在同样的问题,我不能在 JLayeredPane 中使用布局管理器,否则滚动按钮不会出现在聊天的顶部(更高深度)。主要逻辑位于 guiUpdate() 方法中,与布局无关
标签: java swing jscrollpane