Link to home
Start Free TrialLog in
Avatar of Frank-22
Frank-22

asked on

ContentPane problem !

Hi

I got a question regarding size and placement of contentPane.

I have written this addressbook-program.

I got a problem regarding placement of the contentpane.

When I start then program type in a String in firstname TextField afterwhich I press search the resultSet is displayed in the a JTable.
It is here I run into the problem, then the JTable is displayed its displayed inside a contentPane, that is much large than the JTable displayed.
Is it possible to tell the program, that the displayed contentPane must not be larger than the JTable ?
Secondly after doing one successfull search if I decide to do another search the old JTable from the previous search is not removed. Instead a new ContentPane and JTable is generated instead !
So my second question is : How do I make the program erase a previously displayed JTable in the Swing GUI with a new one after doing second search ?

Cheers
Frank

 

import java.sql.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class Addressbook extends JFrame implements ActionListener, WindowListener {
private Connection connection;
private JTable table;
private JTextField firstname;
static
{
     try
     {
          Class.forName( "com.mysql.jdbc.Driver" );
     }
     catch ( ClassNotFoundException cnfex )
     {
          System.err.println( "Failed to load JDBC/ODBC driver." );
          cnfex.printStackTrace();
          System.exit( 1 );
     }

}


public Addressbook()
{
String username = "root";
String password = "";

String url = "jdbc:mysql:///addresstest";
try {
connection = DriverManager.getConnection(url,username, password);
}
catch ( SQLException sqlex ) {
System.err.println( "Unable to connect" );
sqlex.printStackTrace();
}
//deleteRecord();
//updateRecord();
  // All this assembles the frame, so it belongs in the constructor.
    Container cont = getContentPane();
this.setTitle( "Addressbook for ModMail" );
    cont.setLayout(new FlowLayout());

    ImageIcon magnif = new ImageIcon("magnif.gif");
    JLabel label = new JLabel("firstname:");
    JButton button = new JButton("Search", magnif);  
    button.addActionListener(this);
    this.addWindowListener(this);
 
  ImageIcon redX = new ImageIcon("redX.gif");
    JButton button1 = new JButton("Delete", redX);  
    //  button1.addActionListener(this);

   ImageIcon v = new ImageIcon("v.gif");
    JButton button2 = new JButton("Update", v);  
    // button2.addActionListener(this);

  firstname = new JTextField();
    firstname.setPreferredSize(new Dimension(125,20));
    cont.add(label);
    cont.add(firstname);
    cont.add(button);
    cont.add(button1);
    cont.add(button2);
setSize( 550, 125 );
show();
}
public void windowActivated( WindowEvent we ) {};
public void windowClosed( WindowEvent we ) {};
public void windowClosing( WindowEvent we )
{
     System.exit(0);
}
public void windowDeactivated( WindowEvent we ) {};
public void windowDeiconified( WindowEvent we ) {};
public void windowIconified( WindowEvent we ) {};
public void windowOpened( WindowEvent we ) {};
public void actionPerformed( ActionEvent ae )
{
 String str = firstname.getText();
     getTable( str );
}

private void getTable(String str)
{
Statement statement;
ResultSet resultSet;
try {  
    String query = "select* from contacts where firstname like '" + str +"'";
    statement = connection.createStatement();
    resultSet = statement.executeQuery( query );
  displayResultSet( resultSet );
        statement.close();
}
catch ( SQLException sqlex ) {
    sqlex.printStackTrace();

}
}

private void displayResultSet( ResultSet rs )
throws SQLException
{
// position to first record
boolean moreRecords = rs.next();

// If there are no records, display a message
if ( ! moreRecords ) {
JOptionPane.showMessageDialog( this,
"ResultSet contained no records" );
//setTitle( "No records to display");
return;
}

Vector columnHeads = new Vector();
Vector rows = new Vector();

try {
// get column heads
ResultSetMetaData rsmd = rs.getMetaData();

for ( int i = 1; i <= rsmd.getColumnCount(); ++i )
columnHeads.addElement( rsmd.getColumnName( i ) );

// get row data
do {
rows.addElement( getNextRow( rs, rsmd ) );
} while ( rs.next() );

// display table with ResultSet contents
table = new JTable( rows, columnHeads );
JScrollPane scroller = new JScrollPane( table );
getContentPane().add(
scroller, BorderLayout.CENTER );
validate();
}
catch ( SQLException sqlex ) {
sqlex.printStackTrace();
}
}

private Vector getNextRow( ResultSet rs,
ResultSetMetaData rsmd )
throws SQLException
{
Vector currentRow = new Vector();

for ( int i = 1; i <= rsmd.getColumnCount(); ++i )
switch( rsmd.getColumnType( i ) ) {
case Types.VARCHAR:
currentRow.addElement( rs.getString( i ) );
break;
case Types.INTEGER:
currentRow.addElement(
new Long( rs.getLong( i ) ) );
break;
default:
System.out.println( "Type was: " +
rsmd.getColumnTypeName( i ) );
}

return currentRow;
}

public void shutDown()
{
try {
connection.close();
}
catch ( SQLException sqlex ) {
System.err.println( "Unable to disconnect" );
sqlex.printStackTrace();
}
}
public static void main( String args[] ) {
Addressbook adr = new Addressbook();
adr.show();

}
}



Avatar of vk33
vk33

Hi!

1. You can remove any control or container with remove method. e.g.:

JPanel panel = new JPanel();
JButton button = new JButton("ok");
panel.add(button);
...
panel.remove(button);

So, all you need is to keep your scroller reference somewhere in the class. Then you'll be able to remove it.

2. JComponent has 3 methods to control the size: setPreferredSize(), setMaximumSize(), setMinimumSize() which control the component's size. The behavior depends on specific layout manager.

Hope it helps!
Avatar of Frank-22

ASKER

Hi thanks for You answer....

I tried You surgested code, but my contentPane still extends over a much larger part of the frame than the displayed JTable does.

So my first Question still remain:

How do I make my contentPane only extend over the area, which is covered by the JTable.

Maybe it can be done counting the number rows and columns in the ResultSet and using these calculations to extend a contentPane that fits the size of JTable.

Can this be done by using my existing code ? Or is there easier way to do it ?

My second Question from my previous post was about, then trying to do a second search the previous JTable which contained the contens of the resultSet from my first search is not overwritten by the new JTable, instead the new JTable that contains the contens of the new resultSet appears in a new spot in the JFrame.

I tried to add the following command to the sourcecode cont.remove(table); But the new JTable still does not overwrite the old JTable !!

the code I wrote above is that the right way to write over the old JTable with a new one ?

Sincerely
Frank

Hi!

1. Well, basically in Swing you adjust the size of the components to the size of the containers, not vice versa. What layout do you use? For example if you use BorderLayout, your component size will be always equal to the container's size:

getContentPane().setLayout(new BorderLayout());
getContentPane().add(table, BorderLayout.CENTER);

2. Try revalidating/repainting your container after removing the old table:

cont.remove(table);
cont.revalidate();
cont.repaint();

Regards!
Hi

Thanks for You answer..

I use FlowLayout because if change it BorderLayout all my buttons disappear !

If would please look at my source-code in initial post here, and tell me what I'm doing wrong !

I tried to  add  the revalidation/repainting methods you surgested in the bottum of my constructor, but then I try to run the my program i get a very long nullpointer exception !

Am I missing a package or did I add them in the wrong place ?

Sincerely

Frank

 
With FlowLayout the components size is not adjusted to the container. You should use BorderLayout. If you need to display buttons, you can add them on a separate panel:

Container workspace = getContentPane();
workspace.setLayout(new BorderLayout());
JPanel buttonsPane = new JPanel();
buttonsPane.add(new JButton("button1"));
buttonsPane.add(new JButton("button2"));
workspace.add(buttonsPane,BorderLayout.SOUTH);
workspace.add(scroller,BorderLayout.CENTER);

In this case you'll see your buttons on the bottom of the pane and table in the rest part. For displaying buttons on top use NORTH instead of SOUTH. :)

Actually this is how swing is intended to be used. Your window layout should be ready for resizing. You can find a lot of information on designing layouts here:
http://java.sun.com/docs/books/tutorial/uiswing/layout/index.html

As for revalidation, you should put the validation calls just after the remove (not in constructor, of course). And try validate instead...

getContentPane().remove(scroller);
getContentPane().validate();
getContentPane().repaint();
...

Good luck!
Hi

Thanks for all Your help...

Now my table displayed correctly....

But I have one final question is this matter.

Before then I used flowLayout it was possible to highlight a record in JTable by clicking on it once.

Now after changing to BorderLayout a Record in the JTable i suddenly unclickable !

How do I make the clickable again ?

Sincerely

Frank
Hi!

Really? I've never seen anything like this. Could you post the "final release" of your code, please?

Actually Layout manager doesn't affect events handling. It just determines the way the components are sized and positioned, nothing else! Can you edit the data in the table? Double check you have not made any changes to your table component and data model associated with it.

Regards!
Hi

Here is my final source.

My reason for wanting to be able to click on a Record in JTable is that trying to implement a delete/update feature which requires the user to click on the record and there hit either the update or delete button in the Swing Gui !

Sincerely

Frank

import java.sql.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JTextField;

public class Addressbook extends JFrame implements ActionListener {
    private Connection connection;
    private JTable table;
    private JTextField firstname;
    private JScrollPane scroller;
    private JButton button = new JButton("search");
    private JButton button3;
static
{
     try
     {
          Class.forName( "com.mysql.jdbc.Driver" );
     }
     catch ( ClassNotFoundException cnfex )
     {
          System.err.println( "Failed to load JDBC driver." );
          cnfex.printStackTrace();
          System.exit( 1 );
     }

}


public Addressbook()
{
String username = "root";
String password = "";

String url = "jdbc:mysql:///addresstest";
try {
    connection = DriverManager.getConnection(url,username, password);
}
catch ( SQLException sqlex ) {
    System.err.println( "Unable to connect" );
    sqlex.printStackTrace();
}
// All this assembles the frame, so it belongs in the constructor.
    Container cont = getContentPane();
    this.setTitle( "Addressbook for ModMail" );
    //    cont.setLayout(new FlowLayout());


cont.setLayout(new BorderLayout());
JPanel buttonsPane = new JPanel();

ImageIcon greenV = new ImageIcon("greenV.gif");
button3 = new JButton("New", greenV);

 
ImageIcon magnif = new ImageIcon("magnif.gif");
JLabel label = new JLabel("firstname:");
button = new JButton("Search", magnif);  



ImageIcon redX = new ImageIcon("redX.gif");
JButton button1 = new JButton("Delete", redX);  


ImageIcon v = new ImageIcon("v.gif");
JButton button2 = new JButton("Update", v);  


firstname = new JTextField();
scroller = new JScrollPane();
firstname.setPreferredSize(new Dimension(125,20));
   
buttonsPane.add(button3);
buttonsPane.add(button1);
buttonsPane.add(button2);
buttonsPane.add(label);
buttonsPane.add(firstname);
buttonsPane.add(button);

cont.add(buttonsPane,BorderLayout.SOUTH);
cont.add(scroller,BorderLayout.CENTER);
setSize( 600, 150 );

button3.addActionListener(this);
button1.addActionListener(this);
button2.addActionListener(this);
button.addActionListener(this);

}
public void actionPerformed(ActionEvent e) {
    JButton src = (JButton)e.getSource();
    if (src == button) {
      this.getTable(); }
    else if (src == button3) {
      this.launchAnotherFrame();
    }
}

private void getTable()
{
Statement statement;
ResultSet resultSet;

try {  
    String str = firstname.getText();
    String query = "select* from contacts where firstname like '" + str + "'";
    statement = connection.createStatement();
    System.out.println(query);
    resultSet = statement.executeQuery( query );
    displayResultSet( resultSet );
    statement.close();
}
catch ( SQLException sqlex ) {
    sqlex.printStackTrace();

}
}
         private void launchAnotherFrame() {
            JFrame frame = new JFrame();
            frame.setSize(400, 300);
            this.setContents(frame.getContentPane());
            frame.show();
      }

private void setContents(Container cont) {
            }
 


private void displayResultSet( ResultSet rs )
throws SQLException
{
// position to first record
boolean moreRecords = rs.next();

// If there are no records, display a message
if ( ! moreRecords ) {
JOptionPane.showMessageDialog( this,
"ResultSet contained no records" );
//setTitle( "No records to display");
return;
}

Vector columnHeads = new Vector();
Vector rows = new Vector();

try {
// get column heads
ResultSetMetaData rsmd = rs.getMetaData();

for ( int i = 1; i <= rsmd.getColumnCount(); ++i )
columnHeads.addElement( rsmd.getColumnName( i ) );

// get row data
do {
rows.addElement( getNextRow( rs, rsmd ) );
} while ( rs.next() );

// display table with ResultSet contents
table = new JTable( rows, columnHeads );
JScrollPane scroller = new JScrollPane( table );
getContentPane().add(
scroller, BorderLayout.CENTER );
validate();
getContentPane().validate();
}
catch ( SQLException sqlex ) {
sqlex.printStackTrace();
}
}

private Vector getNextRow( ResultSet rs,
ResultSetMetaData rsmd )
throws SQLException
{
Vector currentRow = new Vector();

for ( int i = 1; i <= rsmd.getColumnCount(); ++i )
switch( rsmd.getColumnType( i ) ) {
case Types.VARCHAR:
currentRow.addElement( rs.getString( i ) );
break;
case Types.INTEGER:
currentRow.addElement(
new Long( rs.getLong( i ) ) );
break;
default:
System.out.println( "Type was: " +
rsmd.getColumnTypeName( i ) );
}

return currentRow;
}

public void shutDown()
{
try {
connection.close();
}
catch ( SQLException sqlex ) {
System.err.println( "Unable to disconnect" );
sqlex.printStackTrace();
}
}
public static void main( String args[] ) {
Addressbook adr = new Addressbook();
adr.show();

}
}
ASKER CERTIFIED SOLUTION
Avatar of vk33
vk33

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial