I'm making a simple program that show the teams, the matches and racking goal of Euro2016 in France.
I have some problem with JTable when changing query.
Here is what happens:
when I change from a Table of (for example) 10 rows to another one that contains only 5 rows it works. But if I change from a table that contains 5 rows to another of 10, the table doesn't change, it displays only 5 rows.
Here the code:
public class Euro2016GUI extends JFrame {
private Container container;
private Sfondo pnlSfondo;
JTable table;
JPanel panel;
static Vector<Vector<String>> data = new Vector<Vector<String>>();
static Vector<String> headers = new Vector<String>();
public Euro2016GUI() {
data.removeAll(data);
headers.removeAll(headers);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600, 400);
this.setTitle("Euro2016");
this.setLocationRelativeTo(null);
pnlSfondo = new Sfondo();
container = this.getContentPane();
container.add(pnlSfondo);
}
public void createTable(String pQuery) {
data.removeAll(data);
headers.removeAll(headers);
Control control = new Control();
panel = new JPanel(new BorderLayout());
panel.setSize(300, 300);
panel.setBackground(Color.red);
control.getData(pQuery);
data = control.getData();
headers = control.getHeaders();
//this is the model which contain actual body of JTable
DefaultTableModel model = new DefaultTableModel(data, headers);
table = new JTable(model);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setEnabled(false);
table.setMaximumSize(new Dimension(100, 300));
header_size();
JScrollPane scroll = new JScrollPane(table);
//scroll.setSize(600, 400);
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
this.getContentPane().add(panel);
panel.add(scroll, BorderLayout.CENTER);
}
public void header_size() {
int colonne = table.getColumnModel().getColumnCount();
TableColumn column;
for (int i = 0; i < colonne; i++) {
column = table.getColumnModel().getColumn(i);
column.setPreferredWidth(200);
}
}
public void cleanData() {
if (table != null) {
DefaultTableModel dm = (DefaultTableModel) table.getModel();
dm.setRowCount(0);
table.revalidate();
}
data.removeAll(data);
headers.removeAll(headers);
}
}
CLASS CONTROL
public class Control {
private static Vector<Vector<String>> data = new Vector<Vector<String>>();
private static Vector<String> headers = new Vector<String>();
public void getData(String pQuery) {
// Enter Your MySQL Database Table name in below Select Query.
String query = pQuery;
Connection con = null;
ResultSet rs;
Statement st = null;
int colonne = 0;
data.removeAll(data);
headers.removeAll(headers);
try {
con = DBConnectionPool.getConnection();
st = con.createStatement();
rs = st.executeQuery(query);
ResultSetMetaData rsmd = rs.getMetaData();
colonne = rsmd.getColumnCount();
for (int i = 1; i <= colonne; i++) {
headers.add(rsmd.getColumnName(i));
}
while (rs.next()) {
Vector<String> d = new Vector<String>();
for (int i = 1; i <= colonne; i++) {
d.add(rs.getString(i));
}
data.add(d);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (st != null) {
try {
st.close();
} catch (SQLException ex) {
Logger.getLogger(DataInJTable.class.getName()).log(Level.SEVERE, null, ex);
}
}
if (con != null) {
DBConnectionPool.releaseConnection(con);
}
}
}
public Vector<Vector<String>> getData() {
return this.data;
}
public Vector<String> getHeaders() {
return this.headers;
}
}
HERE THE ACTION LISTENER IN THE MENU:
...
//----ROSE---//
private class OnClickRose implements ActionListener {
Sfondo sfondo;
#Override
public void actionPerformed(ActionEvent e) {
String str = e.getActionCommand();
str = str.replace("[", "");
str = str.replace("]", "");
String sx = "'";
String dx = "'";
String query = query2.concat(sx.concat(str.concat(dx)));
//frame.cleanData();
sfondo = frame.getPnlSfondo();
if (sfondo.isVisible() && sfondo.getParent().isVisible()) {
sfondo.setVisible(false);
}
frame.createTable(query);
}
}
//----CALENDARIO----//
private class OnClickCalendario implements ActionListener {
Sfondo sfondo;
#Override
public void actionPerformed(ActionEvent e) {
frame.cleanData();
sfondo = frame.getPnlSfondo();
if (sfondo.isVisible() && sfondo.getParent().isVisible()) {
sfondo.setVisible(false);
}
frame.createTable(query4);
}
}
//----CLASSIFICA MARCATORI----//
private class OnClickMarcatori implements ActionListener {
Sfondo sfondo;
#Override
public void actionPerformed(ActionEvent e) {
frame.cleanData();
sfondo = frame.getPnlSfondo();
if (sfondo.isVisible() && sfondo.getParent().isVisible()) {
sfondo.setVisible(false);
}
frame.createTable(query3);
}
}
...
Could anybody tell me where I wrong?
Basically to tell the table to refresh itself, you just call the method fireTableDataChanged() of it's table model.
So in your example, after you run the query, you could just call:
((DefaultTableModel)yourTable.getModel()).fireTableDataChanged();
But I suggest you to stop using default table model, and implement your own table model. It's a lot easier to work.
Related
I need to use the object 'urObjectInCell' in mouseListener of 'table' to another class BtnDelete1.
Here's my Mouse Listener Code:
JTable table;
public FirstSwingApp(){
super();
table = new JTable(model);
table.addMouseListener(new MouseAdapter() {
public void mouseClicked(final MouseEvent e) {
if (e.getClickCount() == 1) {
final JTable target = (JTable)e.getSource();
final int row = target.getSelectedRow();
final int column = 1;
// Cast to ur Object type
urObjctInCell = target.getValueAt(row, column);
}
}
});
friendNo = urObjctInCell.toString();
I tried storing the object in friendNo string which has been declared earlier. But I don't think the friendNo is taking the value of the object.
Here's my Class BtnDelete1 code:
public class BtnDelete1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
String fnumber = friendNo;
CallableStatement dstmt = null;
CallableStatement cstmt = null;
ResultSet rs;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/Contact_Manager?user=root");
String SQL = "{call delete_contact (?)}";
String disQuery = "select * from FRIEND";
dstmt = conn.prepareCall(disQuery);
cstmt = conn.prepareCall(SQL);
cstmt.setString(1, fnumber);
cstmt.executeQuery();
rs = dstmt.executeQuery();
ResultSetMetaData metaData = rs.getMetaData();
// names of columns
Vector<String> columnNames = new Vector<String>();
int columnCount = metaData.getColumnCount();
for (int column = 1; column <= columnCount; column++) {
columnNames.add(metaData.getColumnName(column));
}
// data of the table
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while (rs.next()) {
Vector<Object> vector = new Vector<Object>();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
vector.add(rs.getObject(columnIndex));
}
data.add(vector);
}
// It creates and displays the table
model.setDataVector(data, columnNames);
// Closes the Connection
dstmt.close();
System.out.println("Success!!");
} catch (SQLException ex) {
System.out.println("Error in connection: " + ex.getMessage());
}
}
}
The value of urObjectInCell object obtained from mouseListener is to be used to delete a row in the Jtable 'table'.
I think that you may be thinking this out wrong. Rather than trying to mix a MouseListener and an ActionListener in some unholy matrimony, why not instead simply get the selected cell from the JTable when the ActionListener is notified?
You could do this by giving the JTable-holding class a method for extracting a reference to the selected JTable cell, give the ActionListener a reference to this class, and have the ActionListener call this method when it has been notified and its callback method called.
For example say you have a JTable held in a GUI called NoMouseListenerNeeded:
import java.awt.BorderLayout;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
#SuppressWarnings("serial")
public class NoMouseListenerNeeded extends JPanel {
private static final Integer[][] DATA = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
private static final String[] COLS = { "A", "B", "C" };
private DefaultTableModel tblModel = new DefaultTableModel(DATA, COLS);
private JTable table = new JTable(tblModel);
public NoMouseListenerNeeded() {
JPanel btnPanel = new JPanel();
btnPanel.add(new JButton(new MyButtonListener(this)));
setLayout(new BorderLayout());
add(new JScrollPane(table));
add(btnPanel, BorderLayout.PAGE_END);
}
// get data held by selected cell in JTable
// returns null if no cell selected
public Object getSelectedCell() {
int col = table.getSelectedColumn();
int row = table.getSelectedRow();
if (col < 0 || row < 0) {
return null; // no selection made, return null
} else {
return table.getValueAt(row, col);
}
}
private static void createAndShowGui() {
NoMouseListenerNeeded mainPanel = new NoMouseListenerNeeded();
JFrame frame = new JFrame("NoMouseListenerNeeded");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
You could use an ActionListener (or AbstractAction) to get the selected cell by passing the GUI into the listener, and calling the GUI's method that returns the selected data:
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JOptionPane;
#SuppressWarnings("serial")
public class MyButtonListener extends AbstractAction {
private NoMouseListenerNeeded mainGui;
public MyButtonListener(NoMouseListenerNeeded mainGui) {
super("Press Me");
putValue(MNEMONIC_KEY, KeyEvent.VK_P);
this.mainGui = mainGui;
}
#Override
public void actionPerformed(ActionEvent e) {
Object cell = mainGui.getSelectedCell();
if (cell != null) {
String message = "Selection is: " + cell;
JOptionPane.showMessageDialog(mainGui, message, "Selection", JOptionPane.PLAIN_MESSAGE);
}
}
}
I wnat to fill my Table with new Datas which i get by my DataBase(MySQL). I get all datas and create a new Model with them, but if i want to refresh the specific panel, then it wont be repainted.
public class PanelWest extends JPanel implements ActionListener {
private JButton but_selectBP;
private JButton but_selectBPAdr;
private JButton but_selectGerichte;
private GroupLayout layoutGroup;
private Connector stmtExecuter = new Connector();
// private PanelCenter tableViewer = new PanelCenter();
public PanelWest() {
layoutGroup = createLayout();
this.setLayout(layoutGroup);
createButtons();
}
private GroupLayout createLayout() {
GroupLayout layout = new GroupLayout(this);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
return layout;
}
void createButtons() {
this.but_selectBP = new JButton("Kunden anzeigen");
this.but_selectBP.addActionListener(this);
this.but_selectBPAdr = new JButton("Gerichte anzeigen");
this.but_selectBPAdr.addActionListener(this);
this.but_selectGerichte = new JButton("Lieferanten anzeigen");
this.but_selectGerichte.addActionListener(this);
this.layoutGroup.setHorizontalGroup(layoutGroup.createParallelGroup().addComponent(but_selectBP).addComponent(but_selectBPAdr).addComponent(but_selectGerichte));
this.layoutGroup.setVerticalGroup(layoutGroup.createSequentialGroup().addComponent(but_selectBP).addComponent(but_selectBPAdr).addComponent(but_selectGerichte));
}
#Override
public void actionPerformed(ActionEvent e) {
Object src = e.getSource();
if (src.equals(this.but_selectBP)) {
String query = "SELECT * FROM Kunde";
ResultSet rst = this.stmtExecuter.getResultDBData(query);
// this.tableViewer.setTableName("Kunde");
new PanelCenter().createTable(fillHeader(rst), fillData(rst));
}
if (src.equals(this.but_selectBPAdr)) {
String query = "SELECT * FROM Gericht";
ResultSet rst = this.stmtExecuter.getResultDBData(query);
// this.tableViewer.createTable(fillHeader(rst), fillData(rst));
}
if (src.equals(this.but_selectGerichte)) {
String query = "SELECT * FROM Lieferant";
ResultSet rst = this.stmtExecuter.getResultDBData(query);
// this.tableViewer.createTable(fillHeader(rst), fillData(rst));
}
}
private String[] fillHeader(ResultSet rst) {
try {
ResultSetMetaData rstMetaData = rst.getMetaData();
String[] header = new String[rstMetaData.getColumnCount()];
ArrayList<String> headerDetails = new ArrayList<>();
for (int i = 1; i <= rstMetaData.getColumnCount(); i++) {
headerDetails.add(rstMetaData.getColumnName(i));
}
int j = 0;
for(String head : headerDetails){
header[j] = head;
j++;
}
return header;
} catch (SQLException se) {
se.printStackTrace();
}
return null;
}
private Object[][] fillData(ResultSet rst) {
try {
ResultSetMetaData rstMetaData = rst.getMetaData();
int rowCount = 0;
rst.last();
rowCount = rst.getRow();
System.out.println(rowCount + " Rows");
rst.beforeFirst();
Object[][] data = new Object[rowCount][rstMetaData.getColumnCount()];
int row = 0;
while (rst.next()) {
for (int i = 0; i < rstMetaData.getColumnCount(); i++) {
data[row][i] = rst.getObject(i + 1);
}
row++;
}
return data;
} catch (SQLException se) {
System.out.println("Hier bei Fill");
}
return null;
}
}
I use remove, add revalidate and repaint on my jpanel.
void createTable(String[] header, Object[][] data) {
this.tableData = new JTable();
this.tableData.setModel(new MyTableModel(header, data));
this.tableData.setFillsViewportHeight(true);
this.tableData.addKeyListener(this);
this.scrollPaneTable = new JScrollPane(tableData);
this.scrollPaneTable.setSize(500, 500);
this.remove(this.scrollPaneTable);
this.add(this.scrollPaneTable);
this.revalidate();
this.repaint();
}
You don't need to reinitialize the table, table model.
Put some global variables on the top
private MyTableModel tableModel; //Your own table model
private JTable table;
Initialize them on init
public PanelWest() {
layoutGroup = createLayout();
this.setLayout(layoutGroup);
createButtons();
tableModel = new MyTableModel(header, data); //Your own tablemodel
table = new JTable(tableModel); //Hook the model to your table
this.add(table)
//...Do other things else to your table
}
Once you want to update the table, simply clear the rows from the table model and fill with new rows.
And ask JTable to update its data by calling
void createTable(String[] header, Object[][] data){
int cols = header.length;
int rows = data.length;
//Remove all rows from model
tableModel.setRowCount(0); //(As said by HovercraftFullOfEels)
Object[] row = new Object[cols];
for (int j = 0; j < data.length; j++){
for (int i = 0; i < cols; i++){
row[i] = data[j][i];
}
tableModel.addRow(row);
}
tableModel.fireTableDataChanged();
}
Hope it will help.
Thanks for your help.
I add a small test to my createTable method. I create a new window to show the new table datas and it works. i think my jpanel doesn't repaint correctly cause my grouplayout.
this.tableData = new JTable();
this.tableData.setModel(new MyTableModel(header, data));
this.tableData.setFillsViewportHeight(true);
this.tableData.addKeyListener(this);
this.scrollPaneTable = new JScrollPane(tableData);
this.scrollPaneTable.setSize(500, 500);
this.layoutGroup.setVerticalGroup(layoutGroup.createSequentialGroup().addComponent(this.scrollPaneTable, 400, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE).addComponent(this.scrollPaneChanges).addComponent(this.but_user).addComponent(this.but_dataChange));
// JFrame fr = new JFrame("Hello");
// fr.setLayout(null);
// fr.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// fr.setVisible(true);
// fr.add(this.scrollPaneTable);
I have a class A and a class B.
In class A there is a constructor:
public A() {
getSelectedRow();
}
This constructor calls:
public int getSelectedRow() {
System.out.println("The row is : " + table.getSelectedRow());
return table.getSelectedRow();
}
Up to here everything works fine!
The class B then calls the method getSelectedRow() like that:
A results = new A();
System.out.println("YEAH! IT'S: " + results.getSelectedRow());
I just want to find out the selected table row from class A. The problem is that I am getting a null pointer exception and i dont know why. if I dont call the method everything works fine.
CLASS A:
public class AllResultsFromDB extends JFrame {
#SuppressWarnings("compatibility:9056676689615464658")
private static final long serialVersionUID = 188850508334531506L;
GUI ins = new GUI();
JTable table;
public AllResultsFromDB(GUI x) {
final Vector columnNames = new Vector();
final Vector data = new Vector();
this.ins = x;
try {
/** Initializing GUI class
* in order to call
* getSelectedTable() method. **/
Login sgui = new Login();
String dburl = "jdbc:oracle:thin:#localhost:1521:ORCL";
Connection connection = DriverManager.getConnection(dburl, sgui.getUsername(), sgui.getPassword());
// Fetch data from table specified by user
String query = "SELECT * FROM " + ins.getSelectedTable() + " ORDER BY id";
System.out.println(query);
Statement stmt = connection.createStatement();
ResultSet rset = stmt.executeQuery(query);
ResultSetMetaData metad = rset.getMetaData();
int columns = metad.getColumnCount();
// This loop gets the names of the columns
for (int i = 1; i <= columns; i++) {
columnNames.addElement(metad.getColumnName(i));
}
// This loop gets the data inside the rows
while (rset.next()) {
final Vector row = new Vector(columns);
for (int i = 1; i <= columns; i++) {
row.addElement(rset.getObject(i));
}
data.addElement(row);
}
rset.close();
stmt.close();
connection.close();
// Create table with results
table = new JTable(data, columnNames) {
public boolean isCellEditable(int row, int col) {
return false;
}
public Class getColumnClass(int column) {
for (int row = 0; row < getRowCount(); row++) {
Object obj = getValueAt(row, column);
if (obj != null) {
return obj.getClass();
}
}
return Object.class;
}
};
JScrollPane scroll = new JScrollPane(table);
getContentPane().add(scroll);
JPanel panel = new JPanel();
getContentPane().add(panel, BorderLayout.SOUTH);
table.addMouseListener(new MouseListener() {
public void mousePressed(MouseEvent e) {
//System.out.println(table.getSelectedRow());
}
public void mouseReleased(MouseEvent e) {
//System.out.println(table.getSelectedRow());
}
public void mouseEntered(MouseEvent e) {
//System.out.println(table.getSelectedRow());
}
public void mouseExited(MouseEvent e) {
//System.out.println(table.getSelectedRow());
}
public void mouseClicked(MouseEvent e) {
getSelectedRow();
if (e.getClickCount() == 2) {
//System.out.println(table.getSelectedRow());
Profile profile = new Profile();
try {
profile.getData();
//wait(500000);
profile.getImage();
} catch (Exception f) {
}
profile.setVisible(true);
}
}
});
} catch (SQLException e) {
}
}
public AllResultsFromDB(int x) {
x = getSelectedRow();
System.out.println(table.getSelectedRow());
}
public int getSelectedRow() {
System.out.println("The row is : " + table.getSelectedRow());
return table.getSelectedRow();
}
}
CLASS B:
public class Profile extends JFrame {
AllResultsFromDB results = new AllResultsFromDB();
public Profile(AllResultsFromDB x) {
this.results=x;
try {
getData();
getImage();
} catch (Exception e) {
e.printStackTrace();
}
try {
jbInit();
} catch (Exception e) {
e.printStackTrace();
}
}
public void getImage() throws Exception {
JLabel label;
Image img;
ImageIcon pic;
JPanel panel;
img = new ImageIcon("java.jpg").getImage();
pic = new ImageIcon(img);
label = new JLabel("", pic, JLabel.CENTER);
panel = new JPanel(new BorderLayout());
panel.setBounds(new Rectangle(0, 0, 340, 310));
panel.add(label, null);
panel.add(label, BorderLayout.CENTER);
this.getContentPane().setLayout(null);
this.setSize(new Dimension(1148, 336));
this.getContentPane().add(panel, null);
}
public void getData() throws Exception {
String url = "jdbc:oracle:thin:#localhost:1521:ORCL";
String username = "c##lambros";
String password = "16111111";
Connection conn = null;
try {
System.out.println("YEAH! IT'S: " + results.getSelectedRow());
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(url, username, password);
String sql = "SELECT foto FROM criminals WHERE id = 5";
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet resultSet = stmt.executeQuery();
while (resultSet.next()) {
//String name = resultSet.getString(1);
//System.out.println("Name = " + name);
File image = new File("java.jpg");
FileOutputStream fos = new FileOutputStream(image);
byte[] buffer = new byte[256];
//
// Get the binary stream of our BLOB data
//
InputStream is = resultSet.getBinaryStream(1);
while (is.read(buffer) > 0) {
fos.write(buffer);
}
fos.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (conn != null && !conn.isClosed()) {
conn.close();
}
}
}
private void jbInit() throws Exception {
this.setSize(new Dimension(816, 380));
JLabel label;
Image img;
ImageIcon pic;
JPanel panel;
img = new ImageIcon("java.jpg").getImage();
pic = new ImageIcon(img);
label = new JLabel("", pic, JLabel.CENTER);
panel = new JPanel(new BorderLayout());
panel.setBounds(new Rectangle(0, 0, 340, 310));
panel.add(label, null);
panel.add(label, BorderLayout.CENTER);
this.getContentPane().setLayout(null);
this.setSize(new Dimension(1148, 336));
this.getContentPane().add(panel, null);
}
}
In the classB since you are creating a new instance
A results = new A();
The value present in the table.getSelectedRow() also gets created newly and will point to null.
So make sure that you do somthing
A results = new A(selectedRow);
and in the constructor of the A,pass the argument to the function
getSelectedRow(selectedRow);
Please note : Make sure that the value of the "table.selectedRow" is maintained
If table is your instance variable in Class A then it might not be initialized when you are trying to access it in constructor of A.
And calling getSelectedRow from the constructor is not making any sense too.
Try to initialize the table variable in constructor instead of calling that method, it should work after it.
This is because the table object is not being initialized.
Try to initialize the table object in constructor....it is a good practice
I use DefaultTableModel for my JTable model, But not show my table!
public class RecordTableGUI2 extends JFrame {
JTable table;
RecordTableModel2 model2;
public RecordTableGUI2() {
model2 = new RecordTableModel2();
table = new JTable(model2);
add(new JScrollPane(table), BorderLayout.CENTER);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 500);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new RecordTableGUI2();
}
});
}
}
Model Class:
public class RecordTableModel2 extends DefaultTableModel {
Connection con;
Statement statement;
ResultSet result;
String dbUrl = "jdbc:mysql://localhost/mydb";
String query = "Select * from mytable";
Vector data = new Vector();
Vector column = new Vector();
public RecordTableModel2() {
try {
con = DriverManager.getConnection(dbUrl, "root", "2323");
statement = con.createStatement();
result = statement.executeQuery(query);
int c = result.getMetaData().getColumnCount();
for (int i = 1; i <= c; i++) {
column.add(result.getMetaData().getColumnName(i));
System.out.println(result.getMetaData().getColumnName(i)); //prints correct
}
while (result.next()) {
Vector eachRow = new Vector(c);
for (int i = 1; i <= c; i++) {
eachRow.add(result.getString(i));
System.out.println(result.getString(i)); //prints correct
}
data.add(eachRow);
}
} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
try {
if (con != null) {
con.close();
}
if (statement != null) {
statement.close();
}
} catch (SQLException sqlee) {
sqlee.printStackTrace();
}
}
}
}
How to introduce vectors to DefaultTableModel?
Output just show a blank JFrame
Add this at first statement of constructor:
super(data,column);
And declare data and column as static
This program is used to read data from database. In the database,there are three tables pki17, pki18, pkn18. For viewing different tables,JComboBox is used and it works by changing the TableModel of the table. Also by using tableChanged method I made table editable. When a cell value in the table is changed the corresponding value in the database has to change to.
When I use tableChanged and actionPerformed methods together, value in database doesn’t get changed when I’m editing a cell in the swing table. When I remove actionPerformed method, then I can update database by editing table cells.
I need to have both abilities, to choose a table from the database by using JComboBox and update database values by editing values in the swing table.
I think the problem exists because TableModel of the table is changed in both methods. But I don’t know how to solve it.
public class TableCombobox extends JPanel implements ActionListener, TableModelListener {
static JTable table;
static JComboBox box;
static MyTableModel model;
static Connection con = null;
static Statement stmt = null;
public TableCombobox() throws SQLException {
super(new BorderLayout());
table = new JTable(new MyTableModel("pki18"));
table.setPreferredScrollableViewportSize(new Dimension(500, 400));
table.setFillsViewportHeight(true);
table.getModel().addTableModelListener(this);
JScrollPane scrollPane = new JScrollPane(table);
JPanel menuPanel = new JPanel();
menuPanel.setLayout(new BoxLayout(menuPanel, BoxLayout.Y_AXIS));
menuPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1,
Color.black));
String[] dalykas = { "Chose groop", "pki17", "pki18", "pkn18" };
box = new JComboBox(dalykas);
box.setMaximumSize(new Dimension(150, 25));
box.setAlignmentX(Component.LEFT_ALIGNMENT);
box.addActionListener(this);
box.setSelectedIndex(2);
menuPanel.add(box);
JPanel cards = new JPanel(new CardLayout());
cards.add(scrollPane, "view");
add(menuPanel, BorderLayout.LINE_START);
add(cards, BorderLayout.CENTER);
}
public void tableChanged(TableModelEvent e) {
int row = e.getFirstRow();
int col = e.getColumn();
model = (MyTableModel) e.getSource();
String stulpPav = model.getColumnName(col);
Object data = model.getValueAt(row, col);
Object studId = model.getValueAt(row, 0);
System.out.println("tableChanded works");
try {
new ImportData(stulpPav, data, studId);
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
public void actionPerformed(ActionEvent event) {
JComboBox cb = (JComboBox) event.getSource();
String pav = (String) cb.getSelectedItem();
if (pav != "Chose groop") {
try {
model = new MyTableModel(pav);
table.setModel(model);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
private static void GUI() throws SQLException {
JFrame frame = new JFrame("E-gradebook");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new TableCombobox());
frame.pack();
frame.setSize(800, 400);
frame.setVisible(true);
}
public static void main(String[] args) throws SQLException {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost/pki18",
"root", "");
GUI();
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} finally {
if (stmt != null)
stmt.close();
}
}
static Connection getConnection() {
return con;
}
}
public class ImportData {
static Connection con = TableCombobox.getConnection();
public ImportData(String a, Object b, Object c)
throws ClassNotFoundException, SQLException {
Statement stmt = null;
try {
String stulpPav = a;
String duom = b.toString();
String studId = c.toString();
System.out.println(duom);
con.setAutoCommit(false);
stmt = con.createStatement();
stmt.addBatch("update pki18 set " + stulpPav + " = " + duom
+ " where studento_id = " + studId + ";");
stmt.executeBatch();
con.commit();
} catch (BatchUpdateException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (stmt != null)
stmt.close();
con.setAutoCommit(true);
System.out.println("Data was imported to database");
}
}
}
public class MyTableModel extends AbstractTableModel{
static int rowCount;
static Object data [][];
static String columnNames [];
public MyTableModel(String grupName) throws SQLException{
String query ="select Studento_id, vardas_pavarde, 1_semestras,"+
" 2_semestras, egzaminas, bendras_balas "+
"from pki18." + grupName;
ResultSet rs ;
Connection con = TableCombobox.getConnection();
Statement stmt = null;
stmt = con.createStatement();
rs = stmt.executeQuery(query);
rs.last();
rowCount = rs.getRow();
data = new Object[rowCount][6];
rs = stmt.executeQuery(query);
for (int iEil = 0; iEil < rowCount; iEil++){
rs.next();
data[iEil][0] = rs.getLong("Studento_id");
data[iEil][1] = rs.getString("Vardas_Pavarde");
data[iEil][2] = rs.getByte("1_semestras");
data[iEil][3] = rs.getByte("2_semestras");
data[iEil][4] = rs.getByte("Egzaminas");
data[iEil][5] = rs.getByte("bendras_balas");
}
String[] columnName = {"Asmens_kodas","Vardas_Pavarde","1_Semestras"
,"2_Semestras","Egzaminas","Bendras_Balas"};
columnNames = columnName;
}
public int getColumnCount(){
return columnNames.length;
}
public int getRowCount(){
return data.length;
}
public String getColumnName(int col){
return columnNames[col];
}
public Object getValueAt(int row, int col){
return data[row][col];
}
public Class getColumnClass(int col){
return getValueAt(0, col).getClass();
}
public boolean isCellEditable(int row, int col){
return true;
}
public void setValueAt(Object value, int row, int col){
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
In the constructor, you add the table model listener to the current model only:
table.getModel().addTableModelListener(this);
In the action event, however, you replace the table model:
model = new MyTableModel(pav);
table.setModel(model);
As a consequence, the new table model won't have the listener, and you won't receive notifications any more. Have the actionPerformed method add the listener as well, and your problem should be fixed.