代码之家  ›  专栏  ›  技术社区  ›  Frank

如何在JScrollPane中显示底部组件?

  •  1
  • Frank  · 技术社区  · 6 年前

    我有一个Java Swing应用程序,它有一个 JScrollPane 有一些成分 JPanel 在里面。那些 面板 s是在“New”之后创建的 JButton 被点击。我的目标是 滚动面板 滚动到最后一个 面板 创建(即向下滚动)。我试过以下方法:

    JScrollBar vertical = Scroll_Pane.getVerticalScrollBar();
    vertical.setValue(vertical.getMaximum() + 40); 
    

    但没用,最后一次 面板 如果在 滚动面板 . 这是我的最小代码,如何修复?

    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+" ]"; }
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   M. Al Jumaily    6 年前

    您正在分配和更新 JScrollBar 在更新之前。这就是为什么你比最新的 JRadioButton JTextField 没有显示)。修复方法是首先通过 frame.pack(); 然后使用 vertical.setValue(...); 来设定你的价值。改变你的 void Update_Layout() {...} 以下内容:

    output

    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();
        }