Java 如何在JScrollPane中显示底部组件?
我有一个Java Swing应用程序,它有一个Java 如何在JScrollPane中显示底部组件?,java,swing,jscrollpane,Java,Swing,Jscrollpane,我有一个Java Swing应用程序,它有一个JScrollPane,其中有一些组件[multipleJPanels]。这些JPanels是在单击“新建”JButton后创建的。我的目标是使JScrollPane向下滚动到创建的最后一个JPanel(即一直向下滚动)。我尝试了以下方法: JScrollBar vertical = Scroll_Pane.getVerticalScrollBar(); vertical.setValue(vertical.getMaximum() + 40);
JScrollPane
,其中有一些组件[multipleJPanel
s]。这些JPanel
s是在单击“新建”JButton
后创建的。我的目标是使JScrollPane
向下滚动到创建的最后一个JPanel
(即一直向下滚动)。我尝试了以下方法:
JScrollBar vertical = Scroll_Pane.getVerticalScrollBar();
vertical.setValue(vertical.getMaximum() + 40);
但是它不起作用,当JScrollPane
中至少有3个项目时,最后创建的JPanel总是丢失。这是我的最小代码,如何修复
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.io.File;
import java.util.*;
import javax.swing.event.*;
public class Items_Test_Panel extends JPanel
{
public static final long serialVersionUID=26362862L;
static Dimension Screen_Size=Toolkit.getDefaultToolkit().getScreenSize();
static JFrame frame=new JFrame("Items_Test_Panel");
JScrollPane Scroll_Pane;
static int W=495,H=110,Max_H=110,Info_TextArea_H=500,Command_Info_Panel_Width=W-23,Command_Info_Panel_Height=33;
int Item_Count=0;
Color Title_Background_Color=new Color(150,206,236);
Insets An_Inset=new Insets(0,0,0,0);
JPanel Main_Panel;
static String Dir_Data="C:/Dir_Data/",Current_Item_File_Path;
static Process Child;
boolean Show_Password_B=true;
Vector<Command_Info> Command_Info_Vector;
JTextArea Info_TextArea=new JTextArea();
DocumentListener Command_Info_Field_Listener;
Swing_Robot Robot=new Swing_Robot();
ButtonGroup Item_Group=new ButtonGroup(); // Group the radio buttons.
static
{
if (!new File(Dir_Data).exists()) new File(Dir_Data).mkdirs();
}
public Items_Test_Panel(int W,int H)
{
FlowLayout Main_Panel_FL=new FlowLayout();
Main_Panel_FL.setHgap(2);
Main_Panel_FL.setVgap(2);
Max_H=H;
Command_Info_Field_Listener=new DocumentListener()
{
public void removeUpdate(DocumentEvent e) { }
public void insertUpdate(DocumentEvent e) { }
public void changedUpdate(DocumentEvent e) { }
};
Main_Panel=new JPanel(Main_Panel_FL);
Scroll_Pane=new JScrollPane(Main_Panel);
Scroll_Pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel Button_Panel=new JPanel(new FlowLayout(1,36,0));
Button_Panel.setPreferredSize(new Dimension(Command_Info_Panel_Width+22,Command_Info_Panel_Height-6));
add(Button_Panel);
JButton New_Button=new JButton("New");
New_Button.setFont(new Font("Times New Roman",0,15));
New_Button.setForeground(new Color(0,28,128));
New_Button.setMargin(An_Inset);
New_Button.setPreferredSize(new Dimension(56,26));
New_Button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
Out("Command_Info_Vector.size() = "+Command_Info_Vector.size());
Create_Command_Info_Panel(++Item_Count+1,null);
revalidate();
}
});
Button_Panel.add(New_Button);
JPanel Title_Panel=new JPanel(new FlowLayout(0,1,1));
add(Title_Panel);
Title_Panel.setBorder(new EtchedBorder());
Title_Panel.setPreferredSize(new Dimension(Command_Info_Panel_Width+22,Command_Info_Panel_Height-4));
JLabel Id_Label=new JLabel(" # ");
Id_Label.setFont(new Font("Times New Roman",0,15));
Id_Label.setOpaque(true);
Id_Label.setBackground(Title_Background_Color);
Id_Label.setForeground(new Color(0,28,128));
Id_Label.setHorizontalAlignment(SwingConstants.CENTER);
Id_Label.setPreferredSize(new Dimension(69,22));
Title_Panel.add(Id_Label);
JLabel Command_Label=new JLabel("Result");
Command_Label.setFont(new Font("Times New Roman",0,15));
Command_Label.setOpaque(true);
Command_Label.setBackground(Title_Background_Color);
Command_Label.setForeground(new Color(0,28,128));
Command_Label.setHorizontalAlignment(SwingConstants.CENTER);
Command_Label.setPreferredSize(new Dimension(416,22));
Title_Panel.add(Command_Label);
add(Scroll_Pane);
JScrollPane Info_TextArea_ScrollPane=new JScrollPane(Info_TextArea);
Info_TextArea_ScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
Info_TextArea_ScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
Info_TextArea_ScrollPane.setPreferredSize(new Dimension(W-2,Info_TextArea_H));
add(Info_TextArea_ScrollPane);
Load_Data("");
}
void Create_Command_Info_Panel(int Id,final Command_Info A_Command_Info)
{
FlowLayout Panel_FL=new FlowLayout();
Panel_FL.setHgap(1);
Panel_FL.setVgap(1);
JPanel Command_Info_Panel=new JPanel(Panel_FL);
Command_Info_Panel.setBorder(new EtchedBorder());
Command_Info_Panel.setPreferredSize(new Dimension(Command_Info_Panel_Width,Command_Info_Panel_Height));
JRadioButton Id_Button=new JRadioButton("[ "+(Id==-1?Item_Count+1:Id)+" ]");
Id_Button.setFont(new Font("Times New Roman",0,15));
Id_Button.setForeground(new Color(0,28,128));
Id_Button.setPreferredSize(new Dimension(65,26));
Item_Group.add(Id_Button);
Id_Button.setSelected(true);
Command_Info_Panel.add(Id_Button);
JTextField Result_Field=new JTextField(A_Command_Info==null?"":A_Command_Info.Result);
Result_Field.setPreferredSize(new Dimension(398,27));
Result_Field.getDocument().addDocumentListener(Command_Info_Field_Listener);
Command_Info_Panel.add(Result_Field);
Main_Panel.add(Command_Info_Panel);
if (A_Command_Info==null) Command_Info_Vector.add(new Command_Info("[ "+(Item_Count)+" ]","","",""));
Update_Layout();
}
void Load_Data(String Items_Dir)
{
Command_Info A_Command_Info=null;
Main_Panel.removeAll();
Item_Count=0;
Info_TextArea.setText("");
Command_Info_Vector=new Vector();
if (Command_Info_Vector.size()>0)
{
Item_Count=Command_Info_Vector.size();
for (int i=0;i<Command_Info_Vector.size();i++)
{
A_Command_Info=Command_Info_Vector.elementAt(i);
Create_Command_Info_Panel(i+1,A_Command_Info);
}
Item_Count--;
Info_TextArea.setText(A_Command_Info.Info);
}
else Create_Command_Info_Panel(-1,null);
Update_Layout();
}
void Update_Layout()
{
Main_Panel.setPreferredSize(new Dimension(Command_Info_Panel_Width,Item_Count*(Command_Info_Panel_Height+2)+36));
if (Item_Count*(Command_Info_Panel_Height+2)+40<Max_H) Scroll_Pane.setPreferredSize(new Dimension(W-2,Item_Count*(Command_Info_Panel_Height+2)+40));
else Scroll_Pane.setPreferredSize(new Dimension(W-2,Max_H));
Scroll_Pane.revalidate();
Scroll_Pane.repaint();
revalidate();
repaint();
JScrollBar vertical=Scroll_Pane.getVerticalScrollBar();
vertical.setValue(vertical.getMaximum()+40);
Out(" vertical.getMaximum() = "+vertical.getMaximum()+" vertical.getMinimum() = "+vertical.getMinimum());
/*
Online advice of how to adjudt the Scroll_Pane : https://robbamforth.wordpress.com/2015/06/24/java-how-to-scroll-to-a-particular-component-in-jscrollpane-and-gain-focus/
JPanel comp=(JPanel)Main_Panel.getComponent(Main_Panel.getComponentCount()-1);
// vertical.setValue(Main_Panel.getParent().getLocation().y+(Main_Panel.getLocation().y+50));
// JComponent comp=Main_Panel;
// vertical.setValue(comp.getParent().getLocation().y+(comp.getLocation().y+50));
vertical.setValue(250);
comp.requestFocus();
Out(comp.toString());
vertical.repaint();
vertical.revalidate();
*/
if (Item_Count*(Command_Info_Panel_Height+2)+40<Max_H) frame.setPreferredSize(new Dimension(W+17,Item_Count*(Command_Info_Panel_Height+2)+122+Command_Info_Panel_Height+Info_TextArea_H));
else frame.setPreferredSize(new Dimension(W+17,Max_H+82+Command_Info_Panel_Height+Info_TextArea_H));
frame.pack();
frame.revalidate();
frame.repaint();
}
private static void out(String message) { System.out.print(message); }
private static void Out(String message) { System.out.println(message); }
// Create the GUI and show it. For thread safety, this method should be invoked from the event-dispatching thread.
static void Create_And_Show_GUI()
{
final Items_Test_Panel demo=new Items_Test_Panel(W,H);
frame.add(demo);
frame.addWindowListener( new WindowAdapter()
{
public void windowActivated(WindowEvent e) { }
public void windowClosed(WindowEvent e) { }
public void windowClosing(WindowEvent e)
{
System.exit(0);
Child.destroy();
}
public void windowDeactivated(WindowEvent e) { }
public void windowDeiconified(WindowEvent e) { demo.repaint(); }
public void windowGainedFocus(WindowEvent e) { demo.repaint(); }
public void windowIconified(WindowEvent e) { }
public void windowLostFocus(WindowEvent e) { }
public void windowOpening(WindowEvent e) { demo.repaint(); }
public void windowOpened(WindowEvent e) { }
public void windowResized(WindowEvent e) { demo.repaint(); }
public void windowStateChanged(WindowEvent e) { demo.repaint(); }
});
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args)
{
// Schedule a job for the event-dispatching thread : creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() { public void run() { Create_And_Show_GUI(); } });
}
}
class Command_Info
{
String Id,Date,Result,Info;
Command_Info(String Id,String Date,String Result,String Info)
{
this.Id=Id;
this.Date=Date;
this.Result=Result;
this.Info=Info;
}
public String toString() { return "Id = "+Id+" Date = [ "+Date+" ] Result = [ "+Result+" ] Info = [ "+Info+" ]"; }
}
import java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
导入javax.swing.border.*;
导入java.io.File;
导入java.util.*;
导入javax.swing.event.*;
公共类项目测试面板扩展JPanel
{
公共静态最终长serialVersionUID=26362862L;
静态维度Screen_Size=Toolkit.getDefaultToolkit().getScreenSize();
静态JFrame=新JFrame(“项目测试面板”);
JScrollPane滚动窗格;
静态int W=495,H=110,最大H=110,信息文本区域H=500,命令信息面板宽度=W-23,命令信息面板高度=33;
int Item_Count=0;
颜色标题\背景\颜色=新颜色(150206236);
插图A_插图=新插图(0,0,0,0);
JPanel主面板;
静态字符串Dir\u Data=“C:/Dir\u Data/”,当前项目文件路径;
静态过程子;
布尔值Show_Password_B=true;
矢量命令\信息\矢量;
JTextArea Info_TextArea=新的JTextArea();
DocumentListener命令\信息\字段\侦听器;
Swing_Robot Robot=新的Swing_Robot();
ButtonGroup Item_Group=新建ButtonGroup();//将单选按钮分组。
静止的
{
如果(!new File(Dir_Data).exists())新建文件(Dir_Data).mkdirs();
}
公共项目测试面板(int W,int H)
{
FlowLayout主面板\u FL=新的FlowLayout();
主配电盘层安装图(2);
主面板水平设置间隙(2);
Max_H=H;
命令\信息\字段\侦听器=新文档侦听器()
{
public void removeUpdate(DocumentEvent e){}
public void insertUpdate(DocumentEvent e){}
public void changedUpdate(DocumentEvent e){}
};
主面板=新的JPanel(主面板);
滚动窗格=新的JScrollPane(主窗格);
Scroll_Pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel按钮_面板=新JPanel(新流程布局(1,36,0));
按钮面板。设置首选尺寸(新尺寸(命令信息面板宽度+22,命令信息面板高度-6));
添加(按钮面板);
JButton New_按钮=新JButton(“新”);
设置字体(新字体(“Times New Roman”,0,15));
新按钮。设置前景(新颜色(0,28128));
新按钮。设置边距(插入);
新建按钮。设置首选尺寸(新尺寸(56,26));
新建按钮。添加ActionListener(新建ActionListener()
{
已执行的公共无效操作(操作事件evt)
{
Out(“Command_Info_Vector.size()=”+Command_Info_Vector.size());
创建命令信息面板(++项目计数+1,空);
重新验证();
}
});
按钮面板。添加(新按钮);
JPanel标题_面板=新JPanel(新流程布局(0,1,1));
添加(标题面板);
标题_面板订单(新蚀刻边框());
Title_Panel.setPreferredSize(新尺寸(命令信息面板宽度+22,命令信息面板高度-4));
JLabel Id_Label=新的JLabel(“#”);
Id_Label.setFont(新字体(“Times new Roman”,0,15));
Id_标签。设置不透明(真);
Id\u标签。背景(标题\u背景\u颜色);
设置前景(新颜色(0,28128));
Id_标签设置水平对齐(SwingConstants.中心);
Id_标签setPreferredSize(新尺寸(69,22));
标题面板。添加(Id标签);
JLabel命令_标签=新JLabel(“结果”);
命令_Label.setFont(新字体(“Times new Roman”,0,15));
命令_Label.setOpaque(true);
命令\标签.背景(标题\背景\颜色);
命令_Label.set前台(新颜色(0,28128));
命令\u Label.setHorizontalAlignment(SwingConstants.CENTER);
命令_Label.setPreferredSize(新尺寸(416,22));
标题面板。添加(命令标签);
添加(滚动窗格);
JScrollPane Info\u TextArea\u ScrollPane=新的JScrollPane(Info\u TextArea);
信息\文本区域\滚动窗格。设置垂直滚动条策略(JScrollPane.垂直滚动条\始终);
Info_TextArea_ScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HorizontalScrollbar_ALWAYS);
信息文本区域滚动窗格。设置首选大小(新维度(W-2,信息文本区域H));
添加(信息\文本区域\滚动窗格);
加载_数据(“”);
}
无效创建命令信息面板(int Id、最终命令信息和命令信息)
{
FlowLayout面板_FL=新的FlowLayout();
配电盘FL.setHgap(1);
面板层设置间隙(1);
JPanel命令\信息\面板=新的JPanel(面板\ FL);
命令信息面板.设置命令(新的蚀刻边框());
命令信息面板.setPreferredSize(新尺寸(命令信息面板宽度、命令信息面板高度));
JRadioButton Id_Button=新的JRadioButton(“[”+(Id=-1?项目计数+1:Id)+“]);
设置字体(新字体(“Times new Roman”,0,15));
设置前景(新颜色(0,28128));
Id_按钮。设置首选尺寸(新尺寸(65,26));
项目组。添加(Id按钮);
Id_按钮。选择设置(真);
命令信息面板。添加(Id按钮);
JTextField Result\u Field=新的JTextField(A\u Command\u Info==null?“:A\u Command\u Info.Result);
结果_字段setPreferredSize(新维度(398,27));
结果\字段.getDocument().addDocumentListener(命令\信息\字段\侦听器);
命令信息面板。添加(结果字段);
主面板。添加(命令信息面板);
如果(A_Command_Info==null)Command_Info_Vector.add(new Command_Info(“[”+(项目计数)+“]),”,“,”,”);
更新_布局();
}
无效加载\u数据(字符串项\u目录)
{
命令信息A\u命令信息=null;
主面板。卸下所有();
项目计数=0;
Info_TextArea.setText(“”);
命令信息向量=新向量();
如果(命令信息向量大小()>0)
{
Item\u Count=命令\u Info\u Vector.siz
void Update_Layout() {
Main_Panel.setPreferredSize(new Dimension(Command_Info_Panel_Width, Item_Count * (Command_Info_Panel_Height + 2) + 36));
if (Item_Count * (Command_Info_Panel_Height + 2) + 40 < Max_H) {
Scroll_Pane.setPreferredSize(new Dimension(W - 2, Item_Count * (Command_Info_Panel_Height + 2) + 40));
} else {
Scroll_Pane.setPreferredSize(new Dimension(W - 2, Max_H));
}
Scroll_Pane.revalidate();
Scroll_Pane.repaint();
revalidate();
repaint();
Main_Panel.revalidate();
Main_Panel.repaint();
/*
Online advice of how to adjudt the Scroll_Pane : https://robbamforth.wordpress.com/2015/06/24/java-how-to-scroll-to-a-particular-component-in-jscrollpane-and-gain-focus/
JPanel comp=(JPanel)Main_Panel.getComponent(Main_Panel.getComponentCount()-1);
// vertical.setValue(Main_Panel.getParent().getLocation().y+(Main_Panel.getLocation().y+50));
// JComponent comp=Main_Panel;
// vertical.setValue(comp.getParent().getLocation().y+(comp.getLocation().y+50));
vertical.setValue(250);
comp.requestFocus();
Out(comp.toString());
vertical.repaint();
vertical.revalidate();
*/
if (Item_Count * (Command_Info_Panel_Height + 2) + 40 < Max_H) {
frame.setPreferredSize(new Dimension(W + 17, Item_Count * (Command_Info_Panel_Height + 2) + 122 + Command_Info_Panel_Height + Info_TextArea_H));
} else {
frame.setPreferredSize(new Dimension(W + 17, Max_H + 82 + Command_Info_Panel_Height + Info_TextArea_H));
}
//HERE!
frame.pack();
JScrollBar vertical = Scroll_Pane.getVerticalScrollBar();
vertical.setValue(vertical.getMaximum());
Out(" vertical.getMaximum() = " + vertical.getMaximum() + " vertical.getMinimum() = " + vertical.getMinimum());
//frame.pack();//in case you want to pack again, not needed for your fix.
frame.revalidate();
frame.repaint();
}