问题
I have a modal jDialog that i wish to dispose when a particular condition is met after showing the error message in another Dialog using JOptionPane. I have tried to use the dispose() method after the JOptionPane dialog but my modal dialog still opens up. The relevant part of my code is below:
import java.awt.Component;
import java.sql.*;
import java.text.SimpleDateFormat;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
public class ReviewPatients extends javax.swing.JDialog {
public ReviewPatients(java.awt.Frame parent, boolean modal) {
super(parent, modal);
jScrollPane1 = new javax.swing.JScrollPane();
jTable1 = new javax.swing.JTable();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"Name", "Address", "Number"
}
) {
Class[] types = new Class [] {
java.lang.String.class, java.lang.String.class, java.lang.Integer.class
};
boolean[] canEdit = new boolean [] {
false, false, false
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
jScrollPane1.setViewportView(jTable1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 1012, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 526, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE))
);
pack();
jScrollPane1.setVisible(false);
e:
{
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3307/doctor","root","Pranav123");
String query="SELECT * FROM records_table WHERE Name LIKE 'some_name';";
Statement st = con.createStatement();
ResultSet rs= st.executeQuery(query);
DefaultTableModel tmodel = (DefaultTableModel) jTable1.getModel();
//Clearing the table
int rows=tmodel.getRowCount();
while(rows>0)
{
tmodel.removeRow(0);
rows--;
}
jTable1.setModel(tmodel);
while(rs.next())
{
//Putting data into table
tmodel.addRow(new Object[] {rs.getString(1),rs.getString(2),rs.getInt(4)});
jTable1.setModel(tmodel);
}
}
catch(Exception e)
{
System.out.println("Error: "+e);
}
if(jTable1.getRowCount()==0)
{
JOptionPane.showMessageDialog(this, "No records exist!");
dispose();
break e;
}
//Showing data
jScrollPane1.setVisible(true);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
ReviewPatients dialog = new ReviewPatients(new javax.swing.JFrame(), true);
dialog.setVisible(true);
}
});
}
e is the label that I have used to exit the block whenever an error occurs. Any help would be greatly appreciated.
回答1:
All static methods in JOptionPane create modal dialogs, i.e., execution of the code stops until the user dismisses the dialog box. If you want to create non-modal dialogs, use JDialog directly. Refer to Java Swing Tutorial for more information.
Updated:
If I am not wrong, you are trying to do is to NOT show the ReviewPatients
dialog at all when there are no records. If that is the case, the simplest solution is to just replacing dispose()
with System.exit(1)
.
A better solution is check whether there are records in the database, and:
- If there are records, create the
ReviewPatients
dialog and populate the table with the data. - If there is no record, display the
JOptionPane
to inform the user there is no record, and terminate the program.
On a separate note: though permissible, try not to mix AWT components with Swing components (refer to another Stack Overflow answer for the reasons).
回答2:
I see a number of problems, some of which may be relevant:
Repeated calls to
setModel()
are unnecessary and may notify the listening table unexpectedly.A simpler way to clear the
DefaultTableModel
is viasetRowCount(0)
.Instead of checking the view for success, check the model; even better, just show the
JOptionPane
in the exception handler.The dialog's parent should probably be a
JFrame
.Also consider updating the table's model using SwingWorker.
As tested:
import java.sql.*;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
/**
* @see http://stackoverflow.com/a/24220593/230513
*/
public class ReviewPatients extends javax.swing.JDialog {
public ReviewPatients(JFrame parent, boolean modal) {
super(parent, modal);
this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
JTable table = new JTable();
table.setModel(new DefaultTableModel(
new Object[][]{},
new String[]{
"Name", "Address", "Number"
}
) {
Class[] types = new Class[]{
java.lang.String.class, java.lang.String.class, java.lang.Integer.class
};
boolean[] canEdit = new boolean[]{
false, false, false
};
@Override
public Class getColumnClass(int columnIndex) {
return types[columnIndex];
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit[columnIndex];
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(table, javax.swing.GroupLayout.PREFERRED_SIZE, 800, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(table, javax.swing.GroupLayout.PREFERRED_SIZE, 400, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE))
);
pack();
this.setLocationRelativeTo(null);
try {
Class.forName("org.h2.Driver");
Connection con = DriverManager.getConnection("jdbc:h2:file:~/src/java/jdbc/test;IFEXISTS=TRUE", "sa", "");
String query = "SELECT * FROM CUSTOMER;";
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(query);
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.setRowCount(0);
while (rs.next()) {
model.addRow(new Object[]{rs.getInt(1), rs.getString(2), rs.getString(3)});
}
} catch (Exception e) {
System.out.println("Error: " + e);
JOptionPane.showMessageDialog(null, "No records exist!");
}
this.setVisible(true);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
ReviewPatients dialog = new ReviewPatients(f, true);
}
});
}
}
来源:https://stackoverflow.com/questions/24218516/disposing-a-modal-dialog-using-a-condition