When I was working on if-else statements on netbeans IDE, it gave me an advice to change if-else to switch.
So I googled it why I had to use switch instead of if-else, and heres the answer
http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&frm=1&source=web&cd=5&ved=0CFAQFjAE&url=http%3A%2F%2Fwww.ashishpaliwal.com%2Fblog%2F2009%2F08%2Fif-else-vs-switch-%25E2%2580%2593-which-is-better%2F&ei=XAbIUfm8E8ejkAWJ64CYBw&usg=AFQjCNHMSGjKS0cjY_t_rOmKqBuz7VkVEQ&sig2=hVPuZARGnOVwsh0zvc10sw&bvm=bv.48293060,d.dGI
so in short, switch has more performance and readability advantage.
Programming is fun
Monday, June 24, 2013
Found really cool array copy method
I was working on array copy menually, then my IDE netbeans gave me a warning sign.
"You are Copying Arrays Manually."
And it showed me how to do it using System.arraycopy!
I think this IDE is so awesome, and people who made it are geniuses.
I hope I could be like them someday
http://docs.oracle.com/javase/6/docs/api/java/lang/System.html
"You are Copying Arrays Manually."
And it showed me how to do it using System.arraycopy!
I think this IDE is so awesome, and people who made it are geniuses.
I hope I could be like them someday
http://docs.oracle.com/javase/6/docs/api/java/lang/System.html
Thursday, June 20, 2013
How to change background color of a row relate to a column data
In this post, I explain how to change background color according to data of a column.
First, this is my goal.
The first row, second column is "male", and the background color of the row is light gray.
I don't remember where I saw this method, so I cannot give you the reference page.
Also, I'm not quite sure what the prepareRenderer does..
More study is required here
First, this is my goal.
The first row, second column is "male", and the background color of the row is light gray.
As I change the male to female, the background color is changed to Orange.
I will explain this in source code.
package jtbl_color;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
/**
*
* @author Lee
*/
public class ColoredTable extends JPanel{
private JTable table;
private JScrollPane scrollPane;
private MyTableModel model;
private int sexColumn = 1;
// data for the table
private Object[][] data = {
{"Singed", "male", false},
{"Akali", "female", false},
{"Tristina", "female", true},
{"Udyr", "male", false},
{"Janna", "female", true}
};
// column names for the table
private final String[] columnNames = {
"Name", "Sex", "Vegetarian"
};
public ColoredTable() {
super(new BorderLayout());
initComponents();
}
public void initComponents() {
// Initiate the Abstract Table Model
model = new MyTableModel();
// Add TableModelListener to the model
model.addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
// get the event, and check if the changed event is data update
if(e.getType() == TableModelEvent.UPDATE) {
// repaint the row
rowRepaint(table, table.convertRowIndexToView(e.getFirstRow()));
}
}
});
// Add the model to the JTable
table = makeTable(model);
// set the Combo box to sex column
setSexColumn(table.getColumnModel().getColumn(sexColumn));
// Add the table to the JScrollPane
scrollPane = new JScrollPane(table);
// Add the scrollPane to the JPanel
this.add(scrollPane);
}
// set combo box for sex column
public static void setSexColumn(TableColumn sexColumn){
// new combo box
JComboBox comboBox = new JComboBox();
// add male and female items to the combo box
comboBox.addItem("male");
comboBox.addItem("female");
// set combo box to the sex column
sexColumn.setCellEditor(new DefaultCellEditor(comboBox));
}
// repaint the selected row
private static void rowRepaint(JTable table, int row) {
Rectangle r = table.getCellRect(row, 0, true);
r.width = table.getWidth();
table.repaint(r);
}
// make table for changing colors
private JTable makeTable(final MyTableModel model) {
return new JTable(model) {
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
String sex = (String)model.getValueAt(
convertRowIndexToModel(row), sexColumn);
if(sex.equals("female")) {
c.setBackground(Color.ORANGE);
} else if (sex.equals("male")) {
c.setBackground(Color.LIGHT_GRAY);
}
return c;
}
};
}
// Define the model for the table using AbstractTableModel
class MyTableModel extends AbstractTableModel {
// Decide the row count according to the data length
@Override
public int getRowCount() {
return data.length;
}
// decide the column count according to the columnNames length
@Override
public int getColumnCount() {
return columnNames.length;
}
// put the data values into the table.
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data[rowIndex][columnIndex];
}
// put the columnNames values into the table column names
@Override
public String getColumnName(int col){
return columnNames[col];
}
// set if the cells in the table are editable.
// In this example, all the cells are editable
@Override
public boolean isCellEditable(int row, int col) {
return true;
}
// this is for data change.
@Override
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
/*
* JTable uses this method to determine the default renderer/
* editor for each cell. If we didn't implement this method,
* then the last column would contain text ("true"/"false"),
* rather than a check box. (From oracle JTable tutorial)
*/
@Override
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
}
/**
* Create the GUI and show it.
* For thread safety,
* this method should be invoked from the
* event-dispatching thread.
* (from Oracle table tutorial)
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("TableRenderDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
ColoredTable newContentPane = new ColoredTable();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
}
I don't remember where I saw this method, so I cannot give you the reference page.
Also, I'm not quite sure what the prepareRenderer does..
More study is required here
How to share a data among two tables
In this post, I'll explain how to share one data among two table.
First, I will define a DataContainer class that holds all the data I want.
Now I want MyTableModel that extends AbstractTableModel.
(otherwise I should redefine MyTableModel for each table.)
now, let's define Table1 class
Similarly, we need to define Table2. The explanation is omitted since Table2 is identical to Table1
Now we need JFrame that holds the two tables.
First, I will define a DataContainer class that holds all the data I want.
package jtbl_2tbl_abst;
/**
*
* @author Lee
*/
public class DataContainer {
private Object[][] data = {
{"Singed", "male", false},
{"Akali", "female", false},
{"Tristina", "female", true},
{"Udyr", "male", false},
{"Janna", "female", true}
};
private final String[] columnNames = {
"Name", "Sex", "Vegetarin"
};
/**
* @return the data
*/
public Object[][] getData() {
return data;
}
/**
* @param data the data to set
*/
public void setData(Object[][] data) {
this.data = data;
}
public void setData(Object data, int row, int col) {
this.data[row][col] = data;
}
/**
* @return the columnNames
*/
public String[] getColumnNames() {
return columnNames;
}
}
Now I want MyTableModel that extends AbstractTableModel.
(otherwise I should redefine MyTableModel for each table.)
package jtbl_2tbl_abst;
import javax.swing.table.AbstractTableModel;
/**
*
* @author Lee
*/
public class MyTableModel extends AbstractTableModel {
// holds column names and data from outer source
private String[] columnNames;
private Object[][] data;
public MyTableModel(Object[][] data, String[] columnNames) {
this.data = data;
this.columnNames = columnNames;
}
// the explanation is ommitted since I've covered it in the last post
// "Using AbstractTableModel"
@Override
public int getRowCount() {
return data.length;
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public Object getValueAt(int row, int col) {
return data[row][col];
}
@Override
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
@Override
public boolean isCellEditable(int row, int col) {
return true;
}
@Override
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
now, let's define Table1 class
package jtbl_2tbl_abst;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import net.miginfocom.swing.MigLayout;
/**
*
* @author Lee
*/
public class Table1 extends JPanel implements TableModelListener{
// JScrollPane that takes JTable
private JScrollPane scrollPane;
// This is table
private JTable table1;
// this holds data from DataContainer
DataContainer container = new DataContainer();
// this holds AbstractTableModel from MyTableModel
private AbstractTableModel model;
public Table1(DataContainer container) {
super(new MigLayout());
this.container = container;
initComponents();
}
private void initComponents() {
// initiate the table model
model = new MyTableModel(container.getData(), container.getColumnNames());
// initiate the table
table1 = new JTable(model);
// add TableModelListener so that we can change the data, and the
// changed data can be detected
table1.getModel().addTableModelListener(this);
scrollPane = new JScrollPane(table1);
this.add(scrollPane);
}
@Override
public void tableChanged(TableModelEvent e) {
// get the first row that has been changed
int row = e.getFirstRow();
// get the column that has been changed
int column = e.getColumn();
// get the changed model of the table
TableModel model = (TableModel)e.getSource();
// tableChanged method throws -1 when theres no change of row and columns
// but wants to update the whole table.
// And that causes unexpected errors, so I put if(column >=0) to prevent that
if(column >= 0 ) {
String columnName = model.getColumnName(column);
// get the changed data from the table model
Object data = model.getValueAt(row, column);
// apply the change to the container data
container.setData(data, row, column);
}
}
/**
* @return the table1
*/
public JTable getTable1() {
return table1;
}
/**
* @param table1 the table1 to set
*/
public void setTable1(JTable table1) {
this.table1 = table1;
}
/**
* @return the model
*/
public AbstractTableModel getModel() {
return model;
}
/**
* @param model the model to set
*/
public void setModel(AbstractTableModel model) {
this.model = model;
}
}
Similarly, we need to define Table2. The explanation is omitted since Table2 is identical to Table1
package jtbl_2tbl_abst;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import net.miginfocom.swing.MigLayout;
/**
*
* @author Lee
*/
public class Table2 extends JPanel implements TableModelListener{
private JScrollPane scrollPane;
private JTable table2;
private AbstractTableModel model;
DataContainer container = new DataContainer();
public Table2(DataContainer container) {
super(new MigLayout());
this.container = container;
initComponents();
}
public void initComponents() {
model = new MyTableModel(container.getData(), container.getColumnNames());
table2 = new JTable(model);
table2.getModel().addTableModelListener(this);
scrollPane = new JScrollPane(table2);
this.add(scrollPane);
}
@Override
public void tableChanged(TableModelEvent e) {
int row = e.getFirstRow();
int column = e.getColumn();
TableModel model = (TableModel)e.getSource();
if(column >= 0 ) {
String columnName = model.getColumnName(column);
Object data = model.getValueAt(row, column);
System.out.println("changed data: " + data);
container.setData(data, row, column);
}
}
/**
* @return the table2
*/
public JTable getTable2() {
return table2;
}
/**
* @param table2 the table2 to set
*/
public void setTable2(JTable table2) {
this.table2 = table2;
}
/**
* @return the model
*/
public AbstractTableModel getModel() {
return model;
}
/**
* @param model the model to set
*/
public void setModel(AbstractTableModel model) {
this.model = model;
}
}
Now we need JFrame that holds the two tables.
package jtbl_2tbl_abst;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
/**
*
* @author Lee
*/
public class Frame {
// JFrame that holds Table1
JFrame frame1 = new JFrame();
// JFrame that holds Table2
JFrame frame2 = new JFrame();
// This button will open frame2 with Table2
JButton opnBttn = new JButton("Open Table2");
// This button will close frame2 updating the changed data
JButton mdfBttn = new JButton("OK");
// This button will Update frame2(table2) when table1 has been changed
JButton udtBttn = new JButton("Update");
DataContainer container = new DataContainer();
Table1 table1Panel;
Table2 table2Panel;
public Frame() {
initTable1();
initTable2();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Frame();
}
});
}
// initiate Table1
public void initTable1() {
// add ActionListener to opnBttn
opnBttn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
opnBttnClicked(evt);
}
});
// add ActionListener to udtBttn
udtBttn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
udtBttnClicked(evt);
}
});
// initiate Table1 with the sharing data
table1Panel = new Table1(container);
// setup frame1
frame1.setLayout(new MigLayout());
frame1.add(table1Panel, "span, growx, wrap");
frame1.add(opnBttn);
frame1.add(udtBttn);
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.pack();
frame1.setVisible(true);
}
// initiate Table2
public void initTable2() {
// add ActionListener to mdfBttn
mdfBttn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
mdfBttnClicked(evt);
}
});
// initiate Table2 with the sharing data
table2Panel = new Table2(container);
// set up frame2
frame2.setLayout(new MigLayout());
frame2.add(table2Panel, "wrap");
frame2.add(mdfBttn, "center");
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame2.pack();
}
// when opnBttn is clicked, frame2(table2) become visible
public void opnBttnClicked(ActionEvent evt) {
// clikcing the opnBttn when one is editing the table cell will cause
// data lose since the changed value is still in Editor, not in Renderer.
// To send the changed value from Editor to Render, I need the following
if (table1Panel.getTable1().isEditing()) {
table1Panel.getTable1().getCellEditor().stopCellEditing();
}
// open frame2(table2)
frame2.setVisible(true);
}
// when mdfBttn is clicked, frame2 is closed
public void mdfBttnClicked(ActionEvent evt) {
// same as above
if (table2Panel.getTable2().isEditing()) {
table2Panel.getTable2().getCellEditor().stopCellEditing();
}
frame2.setVisible(false);
// notify table1 that the data may have been changed
table1Panel.getModel().fireTableDataChanged();
}
// when udtBttn is clicked, table2 refreshes
public void udtBttnClicked(ActionEvent evt) {
if (table1Panel.getTable1().isEditing()) {
table1Panel.getTable1().getCellEditor().stopCellEditing();
}
table2Panel.getModel().fireTableDataChanged();
}
}
How to debug
my boss taught me how to debug today,
and here's the code.
Put this where error occurs.
Put this where error occurs.
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
Using AbstractTableModel
In this post, I explain how to make a JTable using AbstractTableModel
Using AbstractTableModel is very straight foward, so I will just post
a source code that one can use as a basic form like DefaultTableModel
for more information about AbstractTableModel, check
http://docs.oracle.com/javase/tutorial/uiswing/components/table.html
Using AbstractTableModel is very straight foward, so I will just post
a source code that one can use as a basic form like DefaultTableModel
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package jtbl_ex;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
/**
*
* @author Lee
*/
public class TableOne extends JPanel{
private JTable table;
private JScrollPane scrollPane;
private AbstractTableModel model;
// data for the table
private Object[][] data = {
{null, null, null, null},
{null, null, null, null},
{null, null, null, null},
{null, null, null, null}
};
// column names for the table
private String[] columnNames = {
"Name1", "Name2", "Name3", "Name4"
};
public TableOne() {
// set the Layout for the JPanel
super(new BorderLayout());
initComponents();
}
public void initComponents() {
// Initialize the Abstract Table Model
model = new MyTableModel();
// Add the model to the JTable
table = new JTable(model);
// Add the table to the JScrollPane
scrollPane = new JScrollPane(table);
// Add the scrollPane to the JPanel
this.add(scrollPane);
}
// Define the model for the table using AbstractTableModel
class MyTableModel extends AbstractTableModel{
// Decide the row count according to the data length
@Override
public int getRowCount() {
return data.length;
}
// decide the column count according to the columnNames length
@Override
public int getColumnCount() {
return columnNames.length;
}
// put the data values into the table.
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data[rowIndex][columnIndex];
}
// put the columnNames values into the table column names
@Override
public String getColumnName(int col){
return columnNames[col];
}
// set if the cells in the table are editable.
// In this example, all the cells are editable
@Override
public boolean isCellEditable(int row, int col) {
return true;
}
// this is for data change.
@Override
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
/*
* JTable uses this method to determine the default renderer/
* editor for each cell. If we didn't implement this method,
* then the last column would contain text ("true"/"false"),
* rather than a check box. (From oracle JTable tutorial)
*/
@Override
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
}
/**
* Create the GUI and show it.
* For thread safety,
* this method should be invoked from the
* event-dispatching thread.
* (from Oracle table tutorial)
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("TableRenderDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
TableOne newContentPane = new TableOne();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
}
for more information about AbstractTableModel, check
http://docs.oracle.com/javase/tutorial/uiswing/components/table.html
Thursday, June 13, 2013
Short commnet about MigLayout
Wow
The guy who made MigLayout is a genius.
It is so easy to use, extremely flexible, and many more!
I was using BorderLayout and Grid Layout to build my interface, and was having hard time. But once I've changed the layout to MigLayout,
BOOM!
No more headaches!
I wish there were someone around who could tell me these kind of information..
The guy who made MigLayout is a genius.
It is so easy to use, extremely flexible, and many more!
I was using BorderLayout and Grid Layout to build my interface, and was having hard time. But once I've changed the layout to MigLayout,
BOOM!
No more headaches!
I wish there were someone around who could tell me these kind of information..
Subscribe to:
Comments (Atom)

