I want to add data to a JTable which is situated on a JTabbedpane. Data which I want to insert in JTable is a user input data(TextField) from a different class named (addcontact). cntctus is the tab in which Jtable is situated. it contains a method to insert a new row to JTable.
when I am giving values to tname textfield(user Input) a nullpointerexception occurs on the line :-
//contctus.addData(new Object[]{,,,}
my problem is similar to this, Applied all the solutions mentioned. but still getting nullpointerexception
Data from JTextField to JTable
but in my case, the class for input data is different.
I am providing image for contctus tab. ![.][1]
this is the cntctus class:-
public class cntctus extends JPanel{
JPanel p,tablepanel;
JLabel labelpic;
static JTable table;
int j,i,k=0;
String column[];
Object [][]row;
private static DefaultTableModel model;
public cntctus()
{
String column[]= { "Name","Position","Phone"};
Object [][]row = {{"Prof. g", "Director", "+123456"},
{"Mr. Suir singh", "Assistant Professor", "+9123568989"},
{"Ms. sa", "BI teacher","9468645"},
{"bhbnjk ","nj","k780"},
{"nb","hbj","9798679"}
};
model=new DefaultTableModel(row,column);
labelpic =new JLabel(new ImageIcon("D:\\Workspace\\nikhil\\bin\\Resources\\cont.png"));
table = new JTable(row,column);
TableColumn colum = null;
table.setFont(new Font("Comic Sans MS",15,13));
TableModel tm = table.getModel();
.
.
.
}
//and here is the method for adding new row
public static void addData(Object[] data) {
//String nextrow=Integer.toString(model.getRowCount());
model.addRow(data);
}
I am invoking this method from addcontact class. JTable contains three columns.
now dynamically i want to add more contacts in my JTable with the help of addcontact class.
when i'll be clicking on submit button i wish to put all the three details in Jtable.
a part of Code for addcontact class is :-
public void actionPerformed(ActionEvent aes) {
Object src=aes.getSource();
if(src==submit){
if(tname.getText().equals("")){
JOptionPane.showMessageDialog(null, "Please fill contact name!!");
}
else
{
cntctus.addData( new Object[]{tname.getText(), tpos.getText(), tnum.getText()});
//validate();
}
if(tpos.getText().equals("")){
JOptionPane.showMessageDialog(null, "Please fill contact details!!");
}
if(tnum.getText().equals("")){
JOptionPane.showMessageDialog(null, "Please fill contact number!!");
}
}
Related
I'm working on a small project that involves JTable which requires the user to click a button and add a row to the table (I have named the button as addrow). I have used a custom table model (Mytablemodel) which extends Default table model.
My table is first made up of five rows and 4 columns where afterwards user can click the addrow button to add more rows
Everything in my code works fine except the addrow button which does nothing. I will appreciate any help.
public class AddingNewRows extends JFrame {
JTable mytable;
JButton addrow;
String[] columns={"Admission number","Name","School","Year"};
TableColumn tc;
int defaultrows=5;
int rows=new Mytablemodel().getRowCount(),columnscount=new Mytablemodel().getColumnCount();
List data=new ArrayList();
Mytablemodel mytbm;
//
public AddingNewRows(){
super("adding rows");
for(int initialrows=0; initialrows<5; initialrows++){
String[] items={"1","2","3","4"};
data.add(items);
}
mytbm=new Mytablemodel();
mytable=new JTable(mytbm);
JScrollPane scroll=new JScrollPane(mytable);
addrow=new JButton("ADD ROW");
//
JPanel buttonpanel=new JPanel();
buttonpanel.setLayout(new BoxLayout(buttonpanel,BoxLayout.X_AXIS));
buttonpanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
buttonpanel.add(addrow);
//
add(scroll,BorderLayout.CENTER);
add(buttonpanel,BorderLayout.SOUTH);
addrow.addActionListener(new Myactions());
}
public class Mytablemodel extends DefaultTableModel{
#Override
public String getColumnName(int column) {
return columns[column];
}
#Override
public Object getValueAt(int row, int col){
return ((String[])data.get(row))[col];
}
#Override
public boolean isCellEditable(int row, int col){
return true;
}
#Override
public void setValueAt(Object value,int row, int col){
((Object[])data.get(row))[col]=value;
fireTableCellUpdated(row,col);
}
#Override
public Class getColumnClass(int column){
return getValueAt(0,column).getClass();
}
#Override
public int getColumnCount(){
return columns.length;
}
#Override
public int getRowCount(){
return increaserows;
}
#Override
public void addRow(Object[] mynewdata){
int rownum=data.size();
System.out.println(rownum);
data.add(madata);
fireTableRowsInserted(rownum,rownum);
}
}
//
private class Myactions implements ActionListener{
#Override
public void actionPerformed(ActionEvent event){
if(event.getSource()==addrow){
Object[]newdata={"","","",""};
mytbm.addRow(newdata);
}
}
}
public static void main(String[] args) {
AddingNewRows frame=new AddingNewRows();
frame.setVisible(true);
frame.setSize(400,400);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
}
}
Some notes about your code:
You never should call any of the fireXxx() methods explicitely from the
outside. Those are intended to be called internally by
AbstractTableModel subclasses when needed. Note: IMHO those should
be protected and not public, to avoid use them incorrectly. But for
some reason they made them public.
Your addrow button seems to create a new table model that is not
attached to any JTable so it makes no sense. Your table model should
provide an addRow(...) method in order to add a new row to it. Most
likely you will have to enlarge the two-dimensions array that is the
table model's underlyinig data structure any time a row is added.
As #AndrewThompson already suggested, DefaultTableModel seems a
good match to do what your table model does.
Check rows and columnscount properties initialization. It doesn't
seem right to me.
On the other hand, you say in a comment:
I'm having trouble understanding the fireTableRowsInserted(int,int) method. the parameters themself and
where or when to call the method
This method should be called within the addRow(...) that I've suggested you to create in the second point. This method should enlarge the data structure and notify the TableModelListeners that a new row/s has/have been inserted. The parameters are the first and last indexes respectively. Tipically when you append a new single row to the end of the table model, then both first and last indexes are the same and the new size - 1 of the underlying data structure. Of course, several rows can be inserted and not necessarily at the end of the table model, so you have to figure out the appropriate indexes. See the example shown here which uses a List of custom objects as data structure.
According to your question,You want to add new rows every time the user clicks the addrow button.
Achieve your objective by using DefaultTableModel without creating your own or overriding addrow method.
in my example below,parameters in the DefaultTableModel constructor represents the initial rows(5) and columns(4) that the table will have where after execution, the user can add more rows by clicking the addrow button.
public class AddingNewRows extends JFrame {
DefaultTableModel def;
JTable mytable;
JButton addrow;
//
public AddingNewRows(){
super("adding rows");
def=new DefaultTableModel(5,4);
mytable=new JTable(def);
JScrollPane scroll=new JScrollPane(mytable);
addrow=new JButton("ADD ROW");
//
JPanel buttonpanel=new JPanel();
buttonpanel.setLayout(new BoxLayout(buttonpanel,BoxLayout.X_AXIS));
buttonpanel.add(addrow);
//
add(scroll,BorderLayout.CENTER);
add(buttonpanel,BorderLayout.SOUTH);
addrow.addActionListener(new Myactions());
}
private class Myactions implements ActionListener{
#Override
public void actionPerformed(ActionEvent event){
if(event.getSource()==addrow){
Object[]newdata={"","","",""};
def.addRow(newdata);
}
}
}
public static void main(String[] args) {
AddingNewRows frame=new AddingNewRows();
frame.setVisible(true);
frame.setSize(400,400);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
}
}
I got a quite tricky problem when I do some code on JTable
I need to add one line In JTable when I click "Add" button, and I want one of the columns to render
as a JComboBox
the problem is that when I only add one line, it works fine.
but when I add multiple lines a time, no matter which combobox I choose item from, It will always trigger the last comboBox's event(seems always the same combobox since I have printed the hashcode of jComboBox in MyComboxActionListener class. it's the same).
why is that happens , I can't figure it out. Since It's totally a new comboBox and a new listener when I add one line.
Following is the code.
Thanks in advance.
private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {
ProducedProcedure_new addedProducedProcedure = new ProducedProcedure_new(); // the new item
componentProcedureTableModel.getWorks().add(addedProducedProcedure); //add one line to the table
componentProcedureTableModel.fireTableRowsInserted(componentProcedureTableModel.getRowCount()-1, componentProcedureTableModel.getRowCount()-1);
jTable1.changeSelection(componentProcedureTableModel.getRowCount()-1,0, false, false);
List<String> procedureNames = produceCardManager.getProcedureNames(componentIdTextField.getText().trim(),false); //get the items added to combobox
renderColumnAsCombox(1,procedureNames,addedProducedProcedure); //-------------------------------------------
}
void renderColumnAsCombox(int columnIndex , List<String> items,ProducedProcedure_new producedProcedure) {
TableColumn col = jTable1.getColumnModel().getColumn(columnIndex);
JComboBox comboBox = new JComboBox();
for(String item : items) {
comboBox.addItem(item);
}
MyComboxActionListener myComboxActionListener = new MyComboxActionListener(columnIndex,comboBox,producedProcedure);
comboBox.addActionListener(myComboxActionListener);
col.setCellEditor(new DefaultCellEditor(comboBox));
}
class MyComboxActionListener implements ActionListener { // listen for the select event of the combobox
private JComboBox jComboBox;
private ProducedProcedure_new producedProcedure;
private int columnIndex;
public MyComboxActionListener(int columnIndex,JComboBox jComboBox,ProducedProcedure_new producedProcedure) {
this.columnIndex = columnIndex;
this.jComboBox = jComboBox;
this.producedProcedure = producedProcedure;
}
#Override
public void actionPerformed(ActionEvent e) {
String selectedItem = (String)jComboBox.getSelectedItem();
producedProcedure.getProcedure().setProcedureName(selectedItem);
producedProcedure.getProcedure().setProcedureId(String.valueOf(produceCardManager.getProcedureId(selectedItem)));
producedProcedure.getProcedure().setFactor(produceCardManager.getProcedureFactor(selectedItem)); //automately update the factor
((ComponentProcedureTableModel_new)jTable1.getModel()).fireTableDataChanged();
}
}
This is my TableModel, I have extended AbstractTableModel
class CustomTableModel extends AbstractTableModel
{
String[] columnNames = {"Name","Contact","eMail","Address","City","Pin","State","Type","ID"};
Vector<String[]> data = new Vector<String[]>();
CustomTableModel()
{
try
{
//Using JDBC connection//
while(rs.next())
{
String[] s=new String[9];
s[0]=rs.getString(1);
//System.out.println(s[0]);
s[1]=rs.getString(2);
s[2]=rs.getString(3);
s[3]=rs.getString(4);
s[4]=rs.getString(5);
s[5]=rs.getString(6);
s[6]=rs.getString(7);
s[7]=rs.getString(8);
s[8]=rs.getString(9);
data.add(s);
}
}
catch(Exception e)
{
System.out.println("the exception is :"+e.toString());
}
}
public int getColumnCount() {
int columnCount = columnNames.length;
return columnCount;
}
public int getRowCount() {
int rowCount = data.size();
return rowCount;
}
public Object getValueAt(int rowIndex, int columnIndex) {
return data.get(rowIndex)[columnIndex];
}
public String getColumnName(int column) {
return columnNames[column];
}
public void removeRow(int r)
{
for(int i=0;i<data.size();i++)
{
String[] s = (String[])data.get(i);
if(s[0]==getValueAt(r,0))
{
try
{
//using JDBC connections to delete the data from DB//
//also removing the value from data and also updating the view//
data.remove(data.get(i));
fireTableRowsDeleted(r, r);
}
catch (Exception e)
{
System.out.println(e.toString());
}
break;
}
}
}
//I am using the following code to update the view but it doesnot work//
public void addRow(String[] a)
{
data.add(a);
fireTableRowsInserted(data.size() - 1, data.size() - 1);
}
}
I have a table class which extends CustomTableModel .
class table extends CustomTableModel
{
final JButton editButton = new JButton("Edit");
final JButton deleteButton = new JButton("Delete");
final JTable mytable = new JTable(new CustomTableModel());
.
.
.
}
I have a add button , and in its action listener i use the following code to pass the values that i wanted to add.
String[] a = {"a","b","c","d","e","f","g","h","i"};
table myTableObj = new table();
myTableObj.addRow(a);
Pls let me know where i am going wrong . Thanks
Pls let me know where i am going wrong . Thanks
String[] a = {"a","b","c","d","e","f","g","h","i"};
table myTableObj = new table();
myTableObj.addRow(a);
code lines talking about
create a new row
create a new JTable
row is added to a new JTable
result is that a new JTable is never added to visible Swing GUI
don't do that, why is a new JTable recreated on every JButtons event
add String[] a... to the CustomTableModel directly
for better help sooner post an SSCCE, short, runnable, compilable
The table class makes no sense. It is supposed to be a TableModel that shoud be set into a JTable. Instead you have JTable declared as a field inside this table class (which should be Table btw according to Java naming convention). The result is that when constructing a new table object, a JTable is constructed inside it with another CustomTableModel inside. So the tableModel you are adding rows into is not the tableModel actually used by your JTable.
You can also use the myCustomTable.fireTableStructureChanged();
I am New in java, I have a JTable that can read records from a txt file and show they perfectly.
I want to add a new book to my JFrame that when user select a row on table and clicked the "delete" button, that row should delete and that deleted row records must delete from txt file,too.
my code is this, but it has errors and not seen JTable! :
public class CopyOfAllUserTable extends AbstractTableModel {
Vector data;
Vector column;
public static void main(String[] args){
new CopyOfAllUserTable();
}
public CopyOfAllUserTable() {
String line;
data = new Vector();
column = new Vector();
try {
FileInputStream fis = new FileInputStream("D:\\AllUserRecords.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
StringTokenizer st1 = new StringTokenizer(br.readLine(), " ");
while (st1.hasMoreTokens())
column.addElement(st1.nextToken());
while ((line = br.readLine()) != null) {
StringTokenizer st2 = new StringTokenizer(line, " ");
while (st2.hasMoreTokens())
data.addElement(st2.nextToken());
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
final JFrame frame1=new JFrame();
JTable table=new JTable(data,column);
JButton button1=new JButton("Delete");
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
DefaultTableModel model=new DefaultTableModel(data, column);
JTable table=new JTable(model);
}
});
JPanel panel=new JPanel();
panel.add(table);
panel.add(button1);
frame1.add(panel);
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setBounds(200, 80, 600, 500);
frame1.setVisible(true);
frame1.setEnabled(true);
}
public int getRowCount() {
return data.size() / getColumnCount();
}
public int getColumnCount() {
return column.size();
}
public Object getValueAt(int rowIndex, int columnIndex) {
return (String) data.elementAt((rowIndex * getColumnCount())
+ columnIndex);
}
}
My problem is in delete row, and read records from file to jtable are perfectly successful.
Firstly you're not adding your JTable to the content of the frame.
For containers like: frame.getContentPane() and JPanel you should add the child components by using their #add(...) method.
For example:
final JPanel panel=new JPanel(new BorderLayout());
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
DefaultTableModel model=new DefaultTableModel(data, column);
JTable table=new JTable(model);
panel.add(new JScrollPane(table));
panel.revalidate();
}
});
Note that JPanel default layout is FlowLayout. Second thing - if you want to have headers and scrolling in your JTable you need to wrap it with JScrollPane.
Next - you should revalidate the panel after adding/removing/etc.
The second issue is removing rows from JTable. I usually write a method to handle it:
protected void removeRows(final int[] rows) {
int modelRows[] = new int[rows.length];
for(int i = 0; i < rows.length; ++i) {
modelRows[i] = table.convertRowIndexToModel(rows[i]);
}
Arrays.sort(modelRows);
for(int i = modelRows.length - 1; i >= 0; --i) {
int row = modelRows[i];
model.removeRow(row);
}
model.fireTableDataChanged();
}
The convertRowIndexToModel method converts index returned by JTable#getSelectedRows() or JTable#getSelectedRow() (which are the visible indices) to the model indices. If you set RowSorter for your JTable or you leave it to standard implementation:
table.setAutoCreateRowSorter(true);
You are adding table directly to the panel with out using the JScrollPane. Your table header will not be visible if you do like this,
So instead of this,
JPanel panel=new JPanel();
panel.add(table);
Do this,
JPanel panel=new JPanel();
panel.add(new JScrollPane(table));
Why to use JScrollPane? Read this.
When user selects a row and clicks on delete, then get the selected row and remove it from the table list. As you are using AbstractTableModel then you have to write your custom removeRow(..) method to perform this.
Example:
private boolean removeSelectedRow(int row) {
// Remove the row from the list that the table is using.
dataList.remove(row);
// You need to call fireXXX method to refresh the table model.
fireTableDataChanged();
return true;
// If fail return false;
}
If delete is the action then first get the selected row and then call removeSelectedRow(int) like the following,
private void deleteRow() {
int selectedRow = table.getSelectedRow();
boolean deleteStatus = removeSelectedRow(selectedRow);
// Only if the deletion is success then delete from the file.
if(deleteStatus) {
// Delete it from the file too.
}
}
first you have to make sure that something has been selected: when there is something selected than enable the delete button. please look up the JTable java source code #
http://developer.classpath.org/doc/javax/swing/JTable-source.html
and the following code:
1331: /**
1332: * Receives notification when the row selection changes and fires
1333: * appropriate property change events.
1334: *
1335: * #param event the list selection event
1336: */
1337: public void valueChanged(ListSelectionEvent event)
1338: {
1339: firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
1340: Boolean.FALSE, Boolean.TRUE);
1341: int r = getSelectedRow();
1342: int c = getSelectedColumn();
1343: if (r != lastSelectedRow || c != lastSelectedColumn)
1344: {
1345: Accessible o = getAccessibleAt(lastSelectedRow,lastSelectedColumn);
1347: Accessible n = getAccessibleAt(r, c);
1348: firePropertyChange(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY, o, n);
1350: lastSelectedRow = r;
1351: lastSelectedColumn = c;
1352: }
1353: }
You need to register for the last event to be notified when the selected rows have been changed. Add your own listener to enable the deletebutton based on whether or not a row has been selected which is as you can see in the event itself.
Please use to start with the DefaultTableModel because it will work in 90% of the cases.
And any change is applied to the tabledatamodel which will automatically propogate to the JTable View: normally you never change the view because all selection and scroll information is lost which is something you don't want.
When the delete button is fired the approach is straight forward: there is a row selected, otherwise it is impossible to click it: remove that selected row number from the defaultTableModel, and last but not least I would write simply the entire contents of the datamodel model to the designated file because the table's model hold the actual rows that are indeed displayed in the View.
So please think in terms of models models and models: Views are instantiated only once, packed scrolled etc and than you leave them as is. Models are normally also never changed: you change the contents of the models by adding and or deleting rows. One other tip: use always renderers: those that don't don't, in my humble opinion, don't understand how to work with JTables.
And yes you can leave out the first part to listen for selection changes: sure and pop up a warning to indicate the problem. And in a later stage add the functionality that listens for selection changes to enable and or disable the JButton delete row.
Hope this helps.
I have jFrame2 which contains jTable with 4 columns (the jTable taking data from table in database which contain 20 columns)
Also I have jFrame1 which I have used it to fill database.
What I want to do that when I select row in jTable and click jButton, it must open jframe1 showing all data for that row.
i will clear what i want in points
*i want open jframe1 from jframe2 via jbutton(this task is done and this is the code)
public void actionPerformed(ActionEvent e) {
if(e.getSource()==jButton2){
jframe2 regFace =new jframe2();
regFace.setVisible(true);
}}
*once jframe1 opened by jbutton in jframe2 it must show in it fields all data of selected row in jframe2>>this point mean
........-sql query executed once jfram1 opened by Jbutton in jframe2
.........-showing data in jtextfield taking from database by query i mentioned in line above (this task is done and this is the code but not completed)
try {
dbconnect = new myDbConnection();
ResultSet resultSet =null;
resultSet = dbconnect.excuteQuery("SELECT id, area,location, status1 FROM pledges where id='17'");
while (resultSet.next()){
id.setText(resultSet.getString(1));
area.setText(resultSet.getString(2));
location.setText(resultSet.getString(3));
status.setText(resultSet.getString(4));
// i = Long.parseLong(rs1.getString(1));
}
*in brief i want understand jframe1 that please if you opened by jframe2 execute a query and fill text fields by that query
*this is picture would clear better
here
It sounds like the part you are having trouble with is how to get the selected data from the table into the fields in jframe1.
A lot of this depends on the TableModel that is used in your JTable. Assuming you just used a DefaultTableModel, you can get the selected row data like this:
#Override
public void actionPerformed(ActionEvent e) {
int viewRow = myJTable.getSelectedRow();
int modelRow = myJTable.convertRowIndexToModel(viewRow);
DefaultTableModel model = (DefaultTableModel) myJTable.getModel();
// You will get a compiler warning on the following line, but there's not much you can do about it beside suppress it
Vector<Object> rowVector = (Vector<Object>) model.getDataVector().get(modelRow);
jframe2 regFace =new jframe2();
regFace.setSelectedRow(rowVector);
regFace.setVisible(true);
}
And you would have the following method in your jframe2 class:
public void setSelectedRow(Vector<Object> row ) {
id.setText(row.get(0).toString());
area.setText(row.get(1).toString());
location.setText(row.get(2).toString());
status.setText(row.get(3).toString());
// continue for all columns
}
before i put the answer i would thank #wolfcastle such a nice person.He almost answer the question and i'm just modify it to adapt it with sql query and database.
this is the code for jfrme2
public void actionPerformed(ActionEvent e) {
if(e.getSource()==jButton2){
int viewRow = jTable1.getSelectedRow();
int modelRow = jTable1.convertRowIndexToModel(viewRow);
Object oc= jTable1.getModel().getValueAt(modelRow, 0);
String vv=oc.toString();
DefaultTableModel model = (DefaultTableModel) jTable1.getModel();
jframe1 regFace =new jframe1();
try {
regFace.setSelectedRow(vv);
} catch (SQLException ex) {
Logger.getLogger(showp1.class.getName()).log(Level.SEVERE, null, ex);
}
regFace.setVisible(true);
}
}
and the the code for jframe1
public void setSelectedRow(String row ) throws SQLException {
dbconnect = new myDbConnection();
ResultSet resultSet =null;
System.out.print(row);
resultSet = dbconnect.excuteQuery("SELECT id, area,location, status1 ,date1,insname,oname,bname,street,junction,INSPSITION,recname1 FROM pledges where id='"+row+"'");
while (resultSet.next()){
id.setText(resultSet.getString(1));
area.setText(resultSet.getString(2));
location.setText(resultSet.getString(3));
status.setText(resultSet.getString(4));
date.setText(resultSet.getString(5));
insname.setText(resultSet.getString(6));
oname.setText(resultSet.getString(7));
bname.setText(resultSet.getString(8));
street.setText(resultSet.getString(9));
junction.setText(resultSet.getString(10));
insposition.setText(resultSet.getString(11));
recname.setText(resultSet.getString(12));
}
}