CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Jul 2011
    Posts
    5

    Swing - CardLayout and JTable

    Hi,

    I'm currently writing an ATM in swing and I used CardLayout to switch between the different panels.
    One of the panels is a JTable that supposed to show the client history actions.
    I've put the table in a scrollPane but for some reason it doesn't recognize the end of the panel as the end of table, so my scrollPane doesn't show up. I've tried changing either the size of the table or the scroll but it doesn't work.
    I've included the code of my main frame and the JTable panel.

    Any ideas?


    *(ATM FRAME)
    import java.awt.BorderLayout;
    import java.awt.CardLayout;
    import java.awt.Color;

    import javax.swing.Box;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.WindowConstants;

    public class ATMFrame extends JFrame {
    private static final long serialVersionUID = 1L;

    public ATMFrame getInstance() {
    return this;
    }

    public ATMFrame() {

    this.setTitle("MBank ATM");
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    this.setSize(600, 400);
    //this.setResizable(false);
    this.setLocationRelativeTo(null);

    Color borderColor = new Color(150, 175, 200);
    Color backgroundColor = new Color(170, 212, 255);

    JPanel center = new JPanel(new CardLayout());

    LoginPanel loginPanel = new LoginPanel(center);
    loginPanel.setBackground(backgroundColor);
    loginPanel.setWrongMassage(false);
    center.add(loginPanel, "Login");

    this.getContentPane().setLayout(new BorderLayout());
    this.getContentPane().add(Box.createHorizontalStrut(20), BorderLayout.EAST);
    this.getContentPane().add(Box.createHorizontalStrut(20), BorderLayout.WEST);
    this.getContentPane().add(Box.createVerticalStrut(20), BorderLayout.NORTH);
    this.getContentPane().add(Box.createVerticalStrut(20), BorderLayout.SOUTH);

    this.getContentPane().add(center, BorderLayout.CENTER);

    this.getContentPane().setBackground(borderColor);

    }

    public void setNextPanel(JPanel panel) {
    this.getContentPane().add(panel, BorderLayout.CENTER);
    }

    public static void main(String[] args) {
    ATMFrame atmFrame = new ATMFrame();
    atmFrame.setVisible(true);
    }
    }
    #

    *(ATM History)
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.Vector;

    import javax.swing.BorderFactory;
    import javax.swing.Box;
    import javax.swing.JButton;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.ScrollPaneConstants;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableCellRenderer;

    import ATM.Controller.ActionListHandler;
    import Admin.VO.Display;
    import Admin.VO.VOBalanceAction;
    import Admin.VO.VOCustomer;

    public class DisplayHistoryPanel extends JPanel {

    private static final long serialVersionUID = 5L;
    private final String FONT = "Arial";
    private Color backgroundColor;
    private JPanel cards;

    public DisplayHistoryPanel(VOCustomer customer, Vector<VOBalanceAction> balanceActionList,
    JPanel cards, final Connection conn) {

    this.cards = cards;
    this.backgroundColor = new Color(170, 212, 255);

    JLabel helloLabel = new JLabel("<html><u>" + customer.getName() + " History" + "</u></html>");
    helloLabel.setFont(new java.awt.Font(FONT, 3, 20));

    String[] tableHeaders = { "Balance ID",
    "Customer ID",
    "Action",
    "Commission",
    "Date",
    "Comments" };

    DefaultTableModel model = new DefaultTableModel(tableHeaders, 0);

    int counter = 0;

    while (counter < balanceActionList.size()) {
    VOBalanceAction action = balanceActionList.get(counter);
    Object[] row = { action.getBalance_id(),
    action.getCust_id(),
    action.getAction(),
    Display.NIS(action.getAmount()),
    Display.longToShortDate(action.getDate()),
    action.getComments() };

    model.addRow(row);
    counter++;
    }

    JTable table = new JTable(model) {

    private static final long serialVersionUID = 5L;

    public Dimension getPreferredScrollableViewportSize() {
    return getPreferredSize();
    }

    //Creates shading for even rows
    public Component prepareRenderer(TableCellRenderer renderer, int Index_row, int Index_col) {
    Component comp = super.prepareRenderer(renderer, Index_row, Index_col);

    if (Index_row % 2 == 0 && !isCellSelected(Index_row, Index_col)) {
    comp.setBackground(Color.lightGray);
    } else {
    comp.setBackground(Color.white);
    }
    return comp;
    }

    public boolean isCellEditable(int rowIndex, int colIndex) {
    return false; //Disallow the editing of any cell
    }
    };

    JScrollPane scroll = new JScrollPane(table);
    JButton backButton = new JButton(new ActionListHandler("Back", this.cards));
    backButton.setFont(new java.awt.Font(FONT, 1, 15));
    backButton.setBackground(new Color(150, 160, 170));

    JButton exitButton = new JButton("Exit");
    exitButton.setFont(new java.awt.Font(FONT, 1, 15));
    exitButton.setBackground(new Color(150, 160, 170));
    exitButton.addActionListener(new ActionListener() {

    //Closes the ATM if the button "Exit" is clicked
    @Override
    public void actionPerformed(ActionEvent e) {
    try {
    conn.close();
    } catch (SQLException sqlEx) {
    sqlEx.printStackTrace();
    }
    System.exit(0);
    }
    });

    this.setBackground(backgroundColor);
    this.setLayout(new BorderLayout());

    JPanel northPanel = new JPanel();
    northPanel.setBackground(backgroundColor);
    northPanel.add(helloLabel);

    JPanel centerPanel = new JPanel();
    centerPanel.setBackground(backgroundColor);
    centerPanel.setBorder(BorderFactory.createRaisedBevelBorder());
    centerPanel.add(scroll);

    JPanel southPanel = new JPanel();
    southPanel.setBackground(backgroundColor);
    southPanel.add(backButton);
    southPanel.add(Box.createHorizontalStrut(50));
    southPanel.add(exitButton);

    this.add(northPanel, BorderLayout.NORTH);
    this.add(centerPanel, BorderLayout.CENTER);
    this.add(southPanel, BorderLayout.SOUTH);
    }
    }

    Thanks for any help,

    Alex

  2. #2
    dlorde is offline Elite Member Power Poster
    Join Date
    Aug 1999
    Location
    UK
    Posts
    10,163

    Re: Swing - CardLayout and JTable

    Life is short, and posting a huge chunk of unformatted code doesn't make it any easier...

    It would be far more helpful if you posted an SSCCE enclosed in CODE tags to retain formatting (see my sig).

    Having said that, it's clear that overriding getPreferredScrollableViewportSize() is the problem. Why would you do that, if you don't know that it is essential to, and only used for, correct scroll pane operation?

    Makes me wonder whether it's your code at all...

    It is easier to write an incorrect program than understand a correct one...
    A. Perlis
    Please use &#91;CODE]...your code here...&#91;/CODE] tags when posting code. If you get an error, please post the full error message and stack trace, if present.

  3. #3
    Join Date
    Jul 2011
    Posts
    5

    Re: Swing - CardLayout and JTable

    Quote Originally Posted by dlorde View Post
    Life is short, and posting a huge chunk of unformatted code doesn't make it any easier...

    Having said that, it's clear that overriding getPreferredScrollableViewportSize() is the problem. Why would you do that, if you don't know that it is essential to, and only used for, correct scroll pane operation?

    Makes me wonder whether it's your code at all...
    First things first, your right about the huge chunk of code. I didn't read SSCCE. but now I have and will learn for next time.

    (ATM Frame)
    Code:
    public class ATMFrame extends JFrame {
    	private static final long serialVersionUID = 1L;
    
    	public ATMFrame() {
    
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    		this.setSize(600, 400);
    		this.setResizable(false);
    			
    		JPanel center = new JPanel(new CardLayout());
    
    		DisplayHistoryPanel history = new DisplayHistoryPanel(center);
    		center.add(history, "history");
    		
    		this.getContentPane().setLayout(new BorderLayout());
    		this.getContentPane().add(center, BorderLayout.CENTER);
    	}
    
    	public static void main(String[] args) {
    		ATMFrame atmFrame = new ATMFrame();
    		atmFrame.setVisible(true);
    	}
    }
    (ATM History)
    Code:
    public class DisplayHistoryPanel extends JPanel{
    	private static final long serialVersionUID = 5L;
    	public DisplayHistoryPanel(JPanel cards) {
    
    		JLabel helloLabel = new JLabel("<html><u>Hello </u></html>");
    
    		String[] tableHeaders = { "Balance ID", "Customer ID", "Action",
    				"Amount", "Date", "Comments" };
    
    		DefaultTableModel model = new DefaultTableModel(tableHeaders, 20);
    
    		JTable table = new JTable(model) {
    
    			private static final long serialVersionUID = 5L;
    
    			public Dimension getPreferredScrollableViewportSize() {
    				return getPreferredSize();
    			}
    		};
    
    		JScrollPane scroll = new JScrollPane(table);
    		this.setLayout(new BorderLayout());
    
    		JButton exitButton = new JButton("Exit");
    
    		this.setLayout(new BorderLayout());
    
    		JPanel northPanel = new JPanel();
    
    		northPanel.add(helloLabel);
    
    		JPanel centerPanel = new JPanel();
    		//centerPanel.setLayout(new BorderLayout());
    		centerPanel.add(scroll);
    
    		JPanel southPanel = new JPanel();
    
    		southPanel.add(exitButton);
    
    		this.add(northPanel, BorderLayout.NORTH);
    		this.add(centerPanel, BorderLayout.CENTER);
    		this.add(southPanel, BorderLayout.SOUTH);
    	}
    }
    Second, overriding getPreferredScrollableViewportSize() wasn't the problem. You could put it in a /* */
    and it wouldn't make a difference at all.

    The problem in the end was actually in the centerPanel in the ATMHistory class. I've put it in //.
    Setting it as BorderLayout did the trick.

    Thank you anyway for the SSCCE.
    I do try to make my code better.

    Alex

  4. #4
    Join Date
    Jul 2011
    Posts
    5

    Re: Swing - CardLayout and JTable

    Quote Originally Posted by dlorde View Post
    Life is short, and posting a huge chunk of unformatted code doesn't make it any easier...

    It would be far more helpful if you posted an SSCCE enclosed in CODE tags to retain formatting (see my sig).

    Having said that, it's clear that overriding getPreferredScrollableViewportSize() is the problem. Why would you do that, if you don't know that it is essential to, and only used for, correct scroll pane operation?

    Makes me wonder whether it's your code at all...
    First things first, you're right about the huge chunk of code. I didn't read SSCCE before I posted. my mistake. But now I had and will know better for next time.

    second, the problem actually wasn't with the overriding getPreferredScrollableViewportSize() method at all. You could put it in a /* */ and it wouldn't make a difference.

    the problem in the end was with my centerPanel in ATMHistory. (I've put it in a //). Once it was set as BorderLayout the problem was solved.

    (ATMFrame)
    Code:
    public class ATMFrame extends JFrame {
    	private static final long serialVersionUID = 1L;
    	public ATMFrame() {
    
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    		this.setSize(600, 400);
    		this.setResizable(false);
    			
    		JPanel center = new JPanel(new CardLayout());
    
    		DisplayHistoryPanel history = new DisplayHistoryPanel(center);
    		center.add(history, "history");
    		
    		this.getContentPane().setLayout(new BorderLayout());
    		this.getContentPane().add(center, BorderLayout.CENTER);
    	}
    	public static void main(String[] args) {
    		ATMFrame atmFrame = new ATMFrame();
    		atmFrame.setVisible(true);
    	}
    }
    (ATMHistory)
    Code:
    public class DisplayHistoryPanel extends JPanel{
    	private static final long serialVersionUID = 5L;
    	public DisplayHistoryPanel(JPanel cards) {
    
    		JLabel helloLabel = new JLabel("<html><u>Hello </u></html>");
    		String[] tableHeaders = { "Balance ID", "Customer ID", "Action",
    				"Amount", "Date", "Comments" };
    
    		DefaultTableModel model = new DefaultTableModel(tableHeaders, 20);
    		JTable table = new JTable(model) {
    			
    			private static final long serialVersionUID = 5L;
    			public Dimension getPreferredScrollableViewportSize() {
    				return getPreferredSize();
    			}
    		};
    
    		JScrollPane scroll = new JScrollPane(table);
    		this.setLayout(new BorderLayout());
    		JButton exitButton = new JButton("Exit");
    		
    		this.setLayout(new BorderLayout());
    		JPanel northPanel = new JPanel();
    		northPanel.add(helloLabel);
    
    		JPanel centerPanel = new JPanel();
    		//centerPanel.setLayout(new BorderLayout());
    		centerPanel.add(scroll);
    
    		JPanel southPanel = new JPanel();
    		southPanel.add(exitButton);
    
    		this.add(northPanel, BorderLayout.NORTH);
    		this.add(centerPanel, BorderLayout.CENTER);
    		this.add(southPanel, BorderLayout.SOUTH);
    	}
    }
    Thank you anyway for the SSCCE.

    I do try to make my code better.

    Alex

  5. #5
    dlorde is offline Elite Member Power Poster
    Join Date
    Aug 1999
    Location
    UK
    Posts
    10,163

    Re: Swing - CardLayout and JTable

    Quote Originally Posted by alex.j.r View Post
    First things first, your right about the huge chunk of code. I didn't read SSCCE. but now I have and will learn for next time.
    Good man.

    Second, overriding getPreferredScrollableViewportSize() wasn't the problem. You could put it in a /* */
    and it wouldn't make a difference at all.
    Oh, OK. I'm sorry about that - we must be talking at cross purposes. I thought you were talking about not getting scroll bars displayed correctly.

    I previously created an SSCCE from your original code, and found that, as expected, the scroll bars only appeared correctly when the override was removed.

    When I run the modified code you just posted, the scroll bars still don't appear correctly until the override is removed (it's clearer when ATMFrame is made resizeable).

    So you may have fixed the problem you were posting about (which I misinterpreted), but there still seems to be a problem with the scroll bars of the scroll pane, for which my previous answer still stands.

    I'd be curious to know if your experience is different (i.e. whether you get scroll bars correctly displayed), because overriding getPreferredScrollableViewportSize() will interfere with scroll bar display on all the systems I've used.

    If you have a spare moment, please try this minimal demo, with and without the override of getPreferredScrollableViewportSize():
    Code:
    import javax.swing.*;
    import javax.swing.table.DefaultTableModel;
    import java.awt.*;
    
    public class ScrollTest extends JFrame {
    
        public static void main(String[] args) {
            new ScrollTest();
        }
    
        public ScrollTest() throws HeadlessException {
            super("Scroll Test");
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    
            String[] tableHeaders = { "Column 1", "Column 2", "Column 3",
                    "Column 4", "Column 5", "Column 6" };
    
            DefaultTableModel model = new DefaultTableModel(tableHeaders, 40);
            JTable table = new JTable(model) {
    			public Dimension getPreferredScrollableViewportSize() {
    				return getPreferredSize();
    			}
            };
    
            JScrollPane scroll = new JScrollPane(table);
            JPanel panel = new JPanel();
            panel.add(scroll);
            add(panel);
            setSize(600, 400);
            pack();
            setVisible(true);
        }
    }
    The outcome of any serious research can only be to make two questions grow where only one grew before...
    T. Veblen
    Please use &#91;CODE]...your code here...&#91;/CODE] tags when posting code. If you get an error, please post the full error message and stack trace, if present.

  6. #6
    Join Date
    Jul 2011
    Posts
    5

    Re: Swing - CardLayout and JTable

    Quote Originally Posted by dlorde View Post
    When I run the modified code you just posted, the scroll bars still don't appear correctly until the override is removed (it's clearer when ATMFrame is made resizeable).
    Sorry for the double post. After two days of seeing no change, I thought it wasn't sent properly.

    That was part of the problem. Unless this line was added:
    centerPanel.setLayout(new BorderLayout());

    removing the override still resulted in no scroll pane.

    Quote Originally Posted by dlorde View Post
    I'd be curious to know if your experience is different (i.e. whether you get scroll bars correctly displayed), because overriding getPreferredScrollableViewportSize() will interfere with scroll bar display on all the systems I've used.

    If you have a spare moment, please try this minimal demo, with and without the override of getPreferredScrollableViewportSize():
    Tried your example and saw what you meant. With the override - no go.

    I find it interesting however, that in my example only the change to the centerPanel actually makes any difference. I've tried changing your code so as to make it more like mine (one central panel with 3 borderLayout panels over it) but still only by removing the override you get the scrollpanes.

    Something is overriding the override ???

    Alex

  7. #7
    dlorde is offline Elite Member Power Poster
    Join Date
    Aug 1999
    Location
    UK
    Posts
    10,163

    Re: Swing - CardLayout and JTable

    I don't know exactly what's happening with the layouts, but I don't see how anything can override the override.

    However, the scroll pane relies on getPreferredScrollableViewportSize() to determine when to display scroll bars, and the preferredSize (by default) is the size that the component would like to be in order to display its contents in full. So most of the time, returning the preferred size from getPreferredScrollableViewportSize() will effectively disable the scroll bars, because, if the preferred size is honoured by the layout manager, the scroll pane will always seem to be big enough... or something... it's complicated, and there's no more wine left... I'll get the whiskey

    It's easy to cry "bug" when the truth is that you've got a complex system and sometimes it takes a while to get all the components to co-exist peacefully...
    D. Vargas
    Please use &#91;CODE]...your code here...&#91;/CODE] tags when posting code. If you get an error, please post the full error message and stack trace, if present.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured