Я создаю приложение для чата, в котором я добавляю чаты в JPanel
, прикрепленный к JScrollPane
. Чаты могут быть добавлены и удалены из моего JPanel
, и в этом случае я хочу, чтобы мой JScrollPane
выполнял 3 функции
Если вертикальный scrollBar
не виден (т.е. для прокрутки из-за очень небольшого количества чатов на экране), и когда новый чат входит в панель, в результате чего scrollBar
становится видимым в первый раз, тогда scrollBar
должен прокручиваться до максимального значения, чтобы сделать новый добавленный чат видимым
Если пользователь прокрутил до максимального значения / самого низа scrollPane
, насколько это физически возможно, и когда новый чат входит на панель, максимальное значение scrollBar
становится go вверх, затем выполните то же самое, что и Действие 1
Если пользователь прокрутил чат вверх, чтобы увидеть предыдущие сообщения (т.е. до некоторой случайной точки, которая МЕНЬШЕ, чем МАКСИМАЛЬНОЕ значение scrollBar
), а затем появляется новый чат, тогда в чате должна появиться кнопка прокрутки, и если пользователь нажимает на нее, scrollBar
прокручивается до НОВОГО МАКСИМАЛЬНОГО значения, чтобы сделать вновь добавленное чаты видны
В основном мой алгоритм выглядит следующим образом:
//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
}
Этот алгоритм, к сожалению, не работает, и scrollButton всегда оказывается видимым независимо от того. Вот полный код:
Класс отображения чата для отображения чатов
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);
}
}