?
Solved

ContentPane problem !

Posted on 2003-11-12
9
Medium Priority
?
829 Views
Last Modified: 2013-11-23
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();

}
}



0
Comment
Question by:Frank-22
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
9 Comments
 
LVL 4

Expert Comment

by:vk33
ID: 9730441
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!
0
 

Author Comment

by:Frank-22
ID: 9733433
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

0
 
LVL 4

Expert Comment

by:vk33
ID: 9738541
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!
0
Get real performance insights from real users

Key features:
- Total Pages Views and Load times
- Top Pages Viewed and Load Times
- Real Time Site Page Build Performance
- Users’ Browser and Platform Performance
- Geographic User Breakdown
- And more

 

Author Comment

by:Frank-22
ID: 9738986
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

 
0
 
LVL 4

Expert Comment

by:vk33
ID: 9739155
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!
0
 

Author Comment

by:Frank-22
ID: 9741025
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
0
 
LVL 4

Expert Comment

by:vk33
ID: 9741889
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!
0
 

Author Comment

by:Frank-22
ID: 9742124
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();

}
}
0
 
LVL 4

Accepted Solution

by:
vk33 earned 500 total points
ID: 9745643
Hi!

The problem is not in the Layout manager you use. You just forgot to remove the previous instance of scroller before adding the new one in the displayResultSet method. They overlap and it causes wrong events handling. That's it! :)

Replace the following lines:

private void displayResultSet( ResultSet rs )
throws SQLException
{
.....
// remove the previous scroller instance
getContentPane().remove(scroller);
// wrong: JScrollPane scroller = new JScrollPane( table );
// keep your scroller reference in the class variable:
scroller = new JScrollPane(table);
getContentPane().add(
scroller, BorderLayout.CENTER );
...
}
catch ( SQLException sqlex ) {
sqlex.printStackTrace();
}
}

Good luck!
0

Featured Post

Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

By the end of 1980s, object oriented programming using languages like C++, Simula69 and ObjectPascal gained momentum. It looked like programmers finally found the perfect language. C++ successfully combined the object oriented principles of Simula w…
Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses
Course of the Month12 days, 11 hours left to enroll

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question