Vertical scrollbar in jTable swing does not appear

2019-08-21 19:57发布

问题:

I am a bit new to swings, And i was trying to cough up some code involving Jtable. I find that even though i have added the scrollbar policy the vertical scrollbar does not seem to appear. THe code is pretty shabby.(warning u before hand). But could you please indicate where I need to put in the scrollbar policy. I have tried adding it at a lot of places and it just does not seem to appear.

the other question is how do i make an empty table. As in every time the process button is clicked, i would like to refresh the table. Could u point me in this direction as well.

The directions for usage: just enter a number in the regular nodes textfield like 5 or 10 and click on the process button.

My code :

package ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;

import utils.ThroughputUtility;

/**
 * @author Nathan
 *
 */
public class EntryPoint extends JPanel{
    public boolean isProcesed =false;
    static JFrame frame;

     JTabbedPane jTabbedPane = new JTabbedPane();

    private static final long serialVersionUID = -6490905886388876629L;
    public String messageTobeSent = null;
    public int regularNodeCount =0;

    public static final String MESSAGE_TO_BE_SENT ="  Please Enter the message to be sent. ";

    protected static final String ONE = "1";

    Map<String,Double> regNodeThroughputMap ;
    static JTable tableOfValues;

    Object columnNames[] = { "<html><b>Regular Node Name</b></htm>", "<html><b>Throughput Value Obtained</b></html>"};

    Object rowData[][] = null;
    public EntryPoint() {



        jTabbedPane.setTabPlacement(JTabbedPane.NORTH);
        Font font = new Font("Verdana", Font.BOLD, 12);
        jTabbedPane.setFont(font);

        //Server Side Panel.
         JPanel serverPanel = getServerPanel();       
         jTabbedPane.addTab("Server", serverPanel);

         //Client side Panel.
         JPanel clientPanel = getClientPanel();       
         jTabbedPane.addTab("Client", clientPanel);

    }

    private JPanel getClientPanel() {
        //Heading Label
        JPanel clientPanel = new JPanel();
        JLabel RegularNodeLabel =  new JLabel("<html><u>Throughput Optimization For Mobile BackBone Networks</u></html>");
        RegularNodeLabel.setFont(new Font("Algerian",Font.BOLD,20));
        RegularNodeLabel.setForeground(new Color(176,23,31));

        clientPanel.add(RegularNodeLabel);

        return clientPanel;
    }

    /**Server Side Code
     * @return
     */
    private JPanel getServerPanel() {

        //Heading Label
        JPanel serverPanel = new JPanel(new FlowLayout());
        final Box verticalBox1 = Box.createVerticalBox();
        Box horozontalBox1 = Box.createHorizontalBox();
        Box verticalBox2forsep = Box.createVerticalBox();
        Box horozontalBox2 = Box.createHorizontalBox();


        JPanel heading = new JPanel(new FlowLayout(FlowLayout.CENTER));

        JLabel backBoneNodeLabel =  new JLabel("<html><u>Throughput Optimization For Mobile BackBone Networks</u></html>");
        backBoneNodeLabel.setFont(new Font("Algerian",Font.BOLD,20));
        backBoneNodeLabel.setForeground(new Color(176,23,31));
        backBoneNodeLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

        //Indication of BackBone Node
        JPanel body = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JLabel backBoneNodeID =  new JLabel("Fixed BackBone Node");
        backBoneNodeID.setFont(new Font("Algerian",Font.BOLD,16));
        backBoneNodeID.setForeground(new Color(176,23,31));
        backBoneNodeID.setAlignmentX(Component.CENTER_ALIGNMENT);

        //Seperator
        JLabel seperator =  new JLabel("     ");
        seperator.setFont(new Font("Algerian",Font.BOLD,20));
        seperator.setForeground(new Color(176,23,31));
        verticalBox2forsep.add(seperator);

        //Message label
        JLabel messageLabel = new JLabel("Please enter the Message to be sent:  ");
        messageLabel.setFont(new Font("Algerian",Font.BOLD,16));
        messageLabel.setForeground(new Color(176,23,31));
        messageLabel.setAlignmentX(Component.LEFT_ALIGNMENT);

        //Message Text
        final JTextField messageText = new JTextField(MESSAGE_TO_BE_SENT,25);
        messageText.addFocusListener(new FocusListener() {

            @Override
            public void focusLost(FocusEvent arg0) {
                // TODO Auto-generated method stub

            }

            @Override
            public void focusGained(FocusEvent arg0) {
                if(messageText.getText().trim().equalsIgnoreCase(MESSAGE_TO_BE_SENT.trim())){
                    messageText.setText("");
                }

            }
        });


        horozontalBox1.add(messageLabel);
        horozontalBox1.add(messageText);

        //Regular node attached to backbone nodes.
        JLabel regularNodelabel = new JLabel("Number of Regular nodes to be attached to the backbone node. ");
        regularNodelabel.setFont(new Font("Algerian",Font.BOLD,16));
        regularNodelabel.setForeground(new Color(176,23,31));
        regularNodelabel.setAlignmentX(Component.LEFT_ALIGNMENT);

        //Regular Node text
        final JTextField regularNodeText = new JTextField(ONE,5);
        regularNodeText.addFocusListener(new FocusListener() {

            @Override
            public void focusLost(FocusEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void focusGained(FocusEvent e) {
                if(regularNodeText.getText().trim().equalsIgnoreCase(ONE.trim())){
                    regularNodeText.setText("");
                    tableOfValues = new JTable(0,0);

                }


            }
        });

        horozontalBox2.add(regularNodelabel);
        horozontalBox2.add(regularNodeText);

        //Button for Processing. 
        JButton processbutton = new JButton("Process");
        processbutton.setFont(new Font("Algerian",Font.BOLD,16));
        processbutton.setForeground(new Color(176,23,31));
        processbutton.setAlignmentX(Component.CENTER_ALIGNMENT);

        //Processing on clciking process button
        processbutton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                isProcesed=false;
                Runnable runThread = new Runnable() {

                    @Override
                    public void run() {
                        while(!isProcesed){
                            try {
                                Thread.sleep(50);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                        verticalBox1.add(tableOfValues);
                        isProcesed =false;

                    }
                };
                Thread processThread= new Thread(runThread);
                processThread.start();


                regularNodeCount = Integer.parseInt(regularNodeText.getText().trim());
                regNodeThroughputMap = getThroughPutValues(regularNodeText.getText().trim());
                System.out.println("Map obtained = "+regNodeThroughputMap);
                tableOfValues = populateTable(regNodeThroughputMap);
                isProcesed=true;
                JScrollPane scrollPane = new JScrollPane(tableOfValues);
                scrollPane.add(tableOfValues);
                scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
                verticalBox1.add(scrollPane,BorderLayout.CENTER);
               // verticalBox1.add(scrollPane);


            }
        });

        verticalBox1.add(backBoneNodeID);
        verticalBox1.add(verticalBox2forsep);
        verticalBox1.add(horozontalBox1);
        verticalBox1.add(verticalBox2forsep);
        verticalBox1.add(horozontalBox2);
        verticalBox1.add(verticalBox2forsep);
        verticalBox1.add(processbutton);



        heading.add(backBoneNodeLabel);
        //body.add(backBoneNodeID);
        body.add(verticalBox1);

        serverPanel.add(heading);
        serverPanel.add(body);

        return serverPanel;
    }

    protected JTable populateTable(Map<String,Double> regNodeThroughputMap) {

        /*{ { "Row1-Column1", "Row1-Column2", "Row1-Column3" },
            { "Row2-Column1", "Row2-Column2", "Row2-Column3" } }*/
        rowData = new Object[regularNodeCount+1][2];

         Set<Map.Entry<String, Double>> set = regNodeThroughputMap.entrySet();

         for (Map.Entry<String, Double> me : set) {
             System.out.println("key ="+me.getKey());
             System.out.println("Value ="+me.getValue());
         }

         String[] keys = new String[regularNodeCount+2];
         String[] values = new String[regularNodeCount+2];

         List<String> keyList = new LinkedList<String>();
         List<String> valueList = new LinkedList<String>();
         keyList.add("");
         valueList.add("");

         for(String key:regNodeThroughputMap.keySet()){
             keyList.add(key);
         }

         for(double value:regNodeThroughputMap.values()){
             System.out.println(value);
             valueList.add(Double.toString(value));
         }

         keyList.toArray(keys);
         valueList.toArray(values);

         System.out.println(Arrays.asList(keys));
         System.out.println(Arrays.asList(values));
         rowData[0][0] =columnNames[0];
         rowData[0][1] =columnNames[1];

         for(int i=1;i<=regularNodeCount;i++){
             for(int j=0;j<2;j++){
                 if(j==0)
                     rowData[i][j]=keys[i];
                 if(j==1)
                     rowData[i][j]=values[i];
             }
         }


        return new JTable(rowData, columnNames); 


            //Printing the array
    /*      for (int i =0; i < regularNodeCount; i++) {
                for (int j = 0; j < 2; j++) {
                System.out.print(" " + rowData[i][j]);
                }
                System.out.println("");
                }
*/


    }

    protected Map<String, Double> getThroughPutValues(String regularNodeInput) {
        return ThroughputUtility.generateMapofNodeAndThroughput(regularNodeInput);
    }

    protected static void createAndShowGUI() {
         //Create and set up the window.
        frame = new JFrame("Throughput Optimization for Mobile BackBone Networks");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        EntryPoint splitPaneDemo = new EntryPoint();
        frame.getContentPane().add(splitPaneDemo.jTabbedPane);

        JScrollPane sp = new JScrollPane(tableOfValues);
        sp.setBorder(BorderFactory.createEmptyBorder());
        sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        sp.setHorizontalScrollBarPolicy(JScrollPane .HORIZONTAL_SCROLLBAR_AS_NEEDED);
        frame.setResizable(false);
        //Display the window.
        frame.pack();
        frame.setVisible(true);
        frame.setSize(800,600);




    }


    public static void main(String[] args) {

         try {
                for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                    if ("Nimbus".equals(info.getName())) {
                        UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            } catch (UnsupportedLookAndFeelException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

          javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            });

    }



}

Adding ThroughputUtility.java

package utils;

import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @author Nathan
 *
 */
public class ThroughputUtility {

    public static double MIN =5000;
    public static double MAX =10000;
    public static final double e =Math.E;
    public static final double epsilon = 8.854187 *Math.pow(10,-12); 

    static int regularNodeCount;
    static int counter ;

    /**Generates the map of Node and ThroughPut values
     * @param regularNodeInput
     */
    public static Map<String,Double> generateMapofNodeAndThroughput(String regularNodeInput){
        regularNodeCount = Integer.parseInt(regularNodeInput);
        List<Double> randNodeDistances  =getRandDistanceOfNodes(regularNodeCount);

        Map<String,Double> nodeAndThroughputmap = getThroughputValuesForNodes(randNodeDistances);
        System.out.println(nodeAndThroughputmap);
        return nodeAndThroughputmap;

    }

    /** Obtains the throughput value based on the distances between
     * the regular nodes and the backend Nodes.
     * @param randNodeDistances
     * @return
     */
    private static Map<String, Double> getThroughputValuesForNodes(
            List<Double> randNodeDistances) {
        Map<String,Double> nodeAndThroughputmap = new LinkedHashMap<String, Double>();

        for(double i : randNodeDistances){
            double throughputValue = calculateThroughPut(i);
            nodeAndThroughputmap.put("RegularNode :"+counter, throughputValue);
            counter++;
        }

        return nodeAndThroughputmap;
    }

    private static double calculateThroughPut(double distanceij) {

        double throughput  = 1 /(e*regularNodeCount*distanceij*epsilon);

        return throughput;
    }

    /**Generates the distance dij .
     * @param regularNodeCount
     * @return
     */
    private static List<Double> getRandDistanceOfNodes(int regularNodeCount) {
        List<Double> distnodeNumbers = new LinkedList<Double>();

        for(int i=0;i<regularNodeCount;i++){
            double randnodeNumber = MIN + (double)(Math.random() * ((MAX - MIN) + 1));
            distnodeNumbers.add(randnodeNumber);

        }
        return distnodeNumbers;
    }

    public static void main(String[] args) {
        ThroughputUtility.generateMapofNodeAndThroughput("5");
        /*System.out.println(e);
        System.out.println(epsilon);*/
    }
}

回答1:

The main problem why you can't see the scroll bar is that you add the table to multiple containers.

when clicking the button, you recreate a lot of swing objects (why?), then you start a thread to add the table to the box (why?? be careful with swing and multithreading if you don't know what you are doing). after that (or before, depending on how long the thread is running) you add the table to the scrollpane.

the scrollpane does not contain your table, because you can only use it once.

A quick fix would be something like this: create all you GUI stuff once, leave it out of any action listeners and stuff. if you start the application, it should just show an empty table. don't add the same object into multiple containers! you can control the size of your table and scrollpane by using

table.setPreferredSize(new Dimension(width, height));

if you click the button (that is in your action listener), get all the new data and add it it to the table. e.g. by using something like this.

tableOfValues.getModel().setValueAt(value, row, column);

or create a new table model if you have to:

tableOfValues.setModel(new DefaultTableModel(rowData, columnNames));

That's all I can tell you for now by looking at the code...

edit: in the method populateTable(...) don't create a new table! use the above code to set a new model instead if you have to, or use an existing one and modify its values.



回答2:

  1. You never at the scroll pane to the JFrame as far as I could tell on a quick look
  2. You change the data in the TableModel (or replace the TableModel of the JTable)

See http://docs.oracle.com/javase/tutorial/uiswing/components/table.html



回答3:

I had the same problem, just set JTable preferredsize to null and the scrollbar will show up.

Hope it helps