java - Adding column with header and data to the MyTableModel -
i created class mytablemodel extends defaulttablemodel. , want is, have initialized 3 columns data. inside constructor of mytablemodel set header/data values calling this.addcolumn("first col", first_col_values);
exception "exception in thread "main" java.lang.arrayindexoutofboundsexception: 0 >= 0", how fix this?
public mytablemodel () { // code below tried far fix exception //super(input_row_count, 1); // next 3 lines, expect work, instead exception //this.addcolumn("first column", first_col_values); //this.addcolumn("second column", second_col_values); //this.addcolumn("third column", third_col_values); //tablecolumn column = new tablecolumn(); //column.setmodelindex(0); //column.setheadervalue("string value"); //this.addcolumn(column); }
update:
public class main { public main() { model model = new model(); model.ttablemodel tablemodel = model.new ttablemodel(); model.tcomboboxmodel cboxmodel = model.new tcomboboxmodel(); view view = new view(tablemodel, cboxmodel); new controller(view, model, tablemodel, cboxmodel); } public static void main(string[] args) { new main(); } } import java.util.arraylist; import javax.swing.abstractlistmodel; import javax.swing.comboboxmodel; import javax.swing.table.defaulttablemodel; public class model { private static final int row_count = 8; private arraylist<object> columnsnames = new arraylist<>(); private object[][] data = new object[row_count][0]; private int columnindex; public int getcolumnindex() { return columnindex; } public void increasecolumnindex() { columnindex++; } public void decreasecolumnindex() { columnindex--; } public void displayarraylistobjects() { system.out.println(columnsnames); } class ttablemodel extends defaulttablemodel { public ttablemodel() { //super(new object[][]{{1, 2, 3, 4, 5, 6, 7, 8}, {4, 5, 6, 7}},new string[]{"first", "second", "third"}); this.addcolumn("first", new object[] {1, 2, 3, 4, 5, 6, 7, 8}); this.addcolumn("second", new object[] {1, 2, 3, 4, 5, 6, 7, 8}); this.addcolumn("third", new object[] {1, 2, 3, 4, 5, 6, 7, 8}); } public void addcolumn(string header) { columnsnames.add(header); firetablestructurechanged(); } public void removecolumn() { if (columnindex >= 0 && columnindex < getcolumncount()) { columnsnames.remove(columnindex); firetablestructurechanged(); } } @override public int getcolumncount() { return columnsnames.size(); } @override public string getcolumnname(int column) { return columnsnames.get(column).tostring(); } @override public int getrowcount() { if (data != null) { return data.length; } return 0; } @override public object getvalueat(int row, int col) { return data[row][col]; } } class tcomboboxmodel extends abstractlistmodel implements comboboxmodel { private object selecteditem = null; private arraylist<object> itemlist = new arraylist<>(); public void additem(string item) { this.itemlist.add(item); this.fireintervaladded(item, columnindex, columnindex); } public void removeitem() { if (columnindex >= 0 && columnindex < getsize()) { this.itemlist.remove(columnindex); this.fireintervalremoved(selecteditem, columnindex, columnindex); } } public void updateselecteditem() { if (itemlist.get(0) != null) { selecteditem = itemlist.get(0); } else { if (selecteditem != null) { selecteditem = null; this.firecontentschanged(selecteditem, -1, -1); } } } @override public void setselecteditem(object anobject) { if ((selecteditem != null && !selecteditem.equals(anobject)) || selecteditem == null && anobject != null) { this.selecteditem = anobject; this.firecontentschanged(anobject, -1, -1); } } @override public object getselecteditem() { return selecteditem; } @override public int getsize() { return columnsnames.size(); } @override public object getelementat(int index) { return columnsnames.get(index).tostring(); } } } import java.awt.event.actionevent; import java.awt.event.actionlistener; import mvc1.model.tcomboboxmodel; import mvc1.model.ttablemodel; public class controller { private view view; private model model; private model.ttablemodel tablemodel; private model.tcomboboxmodel cboxmodel; public controller(view view, model model, ttablemodel tablemodel, tcomboboxmodel cboxmodel) { this.view = view; this.model = model; this.tablemodel = tablemodel; this.cboxmodel = cboxmodel; this.view.addbuttonlistener(new buttonactionlistener()); } class buttonactionlistener implements actionlistener { @override public void actionperformed(actionevent e) { string s = e.getactioncommand(); switch (s) { case "add new column": model.increasecolumnindex(); tablemodel.addcolumn("field " + model.getcolumnindex()); break; case "remove column": if (model.getcolumnindex() != 0) { model.decreasecolumnindex(); tablemodel.removecolumn(); } else { view.displayerrormessage("there no column left remove."); } break; case "calculate column": model.displayarraylistobjects(); break; case "final results of rows": break; } } } } import java.awt.borderlayout; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.tablemodel; public class view { private jmenubar menubar; private jmenu menufile; private jmenuitem newmenuitem; private jmenuitem exitmenuitem; private jmenu menuview; private jmenuitem aboutmenuitem; private jbutton addnewcolumnbutton; private jbutton removecolumnbutton; private jbutton calculatecolumnbutton; private jbutton totalresultbutton; private jlabel textlabel; private jtextfield columnfield; private jtextfield finalresultfield; private jcombobox columnlistcb; private jtable table; public view(tablemodel tablemodel, comboboxmodel cboxmodel) { jframe frame = new jframe("mvc"); frame.setdefaultcloseoperation(jframe.exit_on_close); frame.setresizable(false); frame.setjmenubar(getmenubarcomponent()); frame.add(getpanelcomponents(tablemodel, cboxmodel)); frame.pack(); frame.setlocationrelativeto(null); frame.setvisible(true); } void addmenulistener(actionlistener l) { newmenuitem.addactionlistener(l); aboutmenuitem.addactionlistener(l); exitmenuitem.addactionlistener(l); } void addbuttonlistener(actionlistener l) { addnewcolumnbutton.addactionlistener(l); removecolumnbutton.addactionlistener(l); calculatecolumnbutton.addactionlistener(l); totalresultbutton.addactionlistener(l); } void displayerrormessage(string errormessage) { joptionpane.showmessagedialog(null, errormessage, "error message", joptionpane.error_message); } void displayinfomessage(string infomessage) { joptionpane.showmessagedialog(null, infomessage, "information message", joptionpane.information_message); } private jmenubar getmenubarcomponent() { menubar = new jmenubar(); menufile = new jmenu("file"); newmenuitem = new jmenuitem("new"); menufile.add(newmenuitem); menufile.addseparator(); exitmenuitem = new jmenuitem("exit"); menufile.add(exitmenuitem); menuview = new jmenu("view"); aboutmenuitem = new jmenuitem("about me"); menuview.add(aboutmenuitem); menubar.add(menufile); menubar.add(menuview); return menubar; } private jpanel getpanelcomponents(tablemodel tablemodel, comboboxmodel cboxmodel) { jpanel panel = new jpanel(new borderlayout()); panel.setborder(borderfactory.createemptyborder(10, 10, 10, 10)); panel.add(centerpanel(tablemodel), borderlayout.center); panel.add(southpanel(), borderlayout.south); panel.add(eastpanel(cboxmodel), borderlayout.east); return panel; } private jpanel centerpanel(tablemodel tablemodel) { jpanel centerpanel = new jpanel(new gridlayout()); table = new jtable(tablemodel); table.setpreferredscrollableviewportsize(new dimension(450, 150)); table.setautoresizemode(jtable.auto_resize_off); centerpanel.add(new jscrollpane(table)); return centerpanel; } private jpanel southpanel() { jpanel southpanel = new jpanel(new flowlayout(flowlayout.left, 5, 5)); totalresultbutton = new jbutton("final results of rows"); southpanel.add(totalresultbutton); textlabel = new jlabel("total result:"); southpanel.add(textlabel); finalresultfield = new jtextfield(); finalresultfield.setpreferredsize(new dimension(50, 25)); southpanel.add(finalresultfield); return southpanel; } private jpanel eastpanel(comboboxmodel cboxmodel) { jpanel eastpanel = new jpanel(new flowlayout(flowlayout.center, 5, 0)); box eastpanelbox = box.createverticalbox(); addnewcolumnbutton = new jbutton("add new column"); addnewcolumnbutton.setalignmentx(box.center_alignment); eastpanelbox.add(addnewcolumnbutton); eastpanelbox.add(box.createverticalstrut(5)); removecolumnbutton = new jbutton("remove column"); removecolumnbutton.setalignmentx(box.center_alignment); eastpanelbox.add(removecolumnbutton); eastpanelbox.add(box.createverticalstrut(5)); columnfield = new jtextfield(); columnfield.setalignmentx(box.center_alignment); columnfield.setpreferredsize(new dimension(130, 25)); eastpanelbox.add(columnfield); eastpanelbox.add(box.createverticalstrut(5)); columnlistcb = new jcombobox(cboxmodel); columnlistcb.setalignmentx(box.center_alignment); eastpanelbox.add(columnlistcb); // might need remove eastpanelbox.add(box.createverticalstrut(5)); calculatecolumnbutton = new jbutton("calculate column"); calculatecolumnbutton.setalignmentx(box.center_alignment); eastpanelbox.add(calculatecolumnbutton); eastpanel.add(eastpanelbox); return eastpanel; } }
you don't provide code can guess first_col_values
etc not initialized (perhaps invalid length?) or perhaps replacing model somewhere else in code. displaying 3 columns data simple can seen below.
note runnable example. if provide similar 1 code able explain in more detail error is.
package gui.table; import java.awt.dimension; import javax.swing.jframe; import javax.swing.jscrollpane; import javax.swing.jtable; import javax.swing.swingutilities; import javax.swing.table.defaulttablemodel; public class threecolumndemo { public static class threecolumnmodel extends defaulttablemodel { public threecolumnmodel() { // initialize 3 rows 0 columns super(3, 0); // add columns data each row this.addcolumn("first column", new string[] {"value1_1", "value2_1", "value3_1" }); this.addcolumn("second column", new string[] {"value1_2", "value2_2", "value3_2" }); this.addcolumn("third column", new string[] {"value1_3", "value2_3", "value3_3" }); } } public static void main(string[] args) { swingutilities.invokelater( new runnable() { @override public void run() { jframe window = new jframe("3-column demo"); window.setpreferredsize(new dimension(600, 400)); window.setdefaultcloseoperation(jframe.exit_on_close); jtable table = new jtable( new threecolumnmodel() ); // put table in scroll pane column headers visible window.add(new jscrollpane(table)); window.pack(); window.setlocationrelativeto(null); window.setvisible(true); } }); } }
update 1: not correctly extending defaulttablemodel
. when call addcolumn(...)
during constructor, parent inserts new column name , while tries make room rows/columns calls methods getcolumncount()
, getcolumnname()
etc override. model not use underlying data of parent checks new structure (an arraylist
) empty @ moment. parent object encounters incosistent behaviour (i.e. added new column , getcolumncount()
returns 0
). comment out following methods , code work: getcolumncount()
, getcolumnname()
, getrowcount()
, getvalueat()
.
then should decide want do. defaulttablemodel
has data structure store data. if extend use structures , not overide methods perform same behaviour parent shake of it. should extend if want add additional behaviour.
if on other hand want use own data structure , own way add/remove columns , rows extend abstracttablemodel
.
update 2: regarding abstracttablemodel
, questions: model name says. way model data. same thing when use object[]
or array of arrays, or arraylist<object>
in case. model rather poor. table model encapsulates abstract data structure can matches needs no matter how complex (i.e. jtree
uses encapsulate hierarchical structure of tree nodes).
swing components behave same way: update model , use events (usually calling firexxx()
) notify corresponding component redraw itself.
in case if need add/remove columns should have method addcolumn/removecolumn
called externally i.e. after create table. model update data internally , call appropriate firexxx
methods. regarding data type should use, use whatever more convenient you. in example using integer
data type object[]
or integer[]
or corresponding arraylist
make sense. if use more complicated data type can introduce new column
class encapsulate data. can complicated need be.