Friday, February 28, 2014

java.sql.SQLException: ORA-01722: invalid number

When the following sql is used to query a database, it throws "java.sql.SQLException: ORA-01722: invalid number" exception.

       String name = "Apple";

       String sql = new StringBuilder("SELECT * FROM fruit ");
       sql.append("WHERE name = ").append(name).toString(); 

To fix the exception, do one of the followings.

1. Indicate that name is a string in the sql by putting single quotes around it

       String sql = new StringBuilder("SELECT * FROM fruit ");
       sql.append("WHERE name = '").append(name).append("'").toString();

2. Use java.sql.Statement to set the value

       Get your database java.sql.Connection object. Then, change the sql to the following.

       String sql = new StringBuilder("SELECT * FROM fruit ");
        sql.append("WHERE name = ?").toString(); 

       Use the PreparedStatement to set the value.
       java.sql.PreparedStatement statement = conn.prepareStatement(sql);
       statement.setString(1, name);

----------------------------------------------------------------------------------------------------------------
                        

If you have ever asked yourself these questions, this is the book for you. What is the meaning of life? Why do people suffer? What is in control of my life? Why is life the way it is? How can I stop suffering and be happy? How can I have a successful life? How can I have a life I like to have? How can I be the person I like to be? How can I be wiser and smarter? How can I have good and harmonious relations with others? Why do people meditate to achieve enlightenment? What is the true meaning of spiritual practice? Why all beings are one? Read the book free here.
      

Thursday, February 27, 2014

Java how to read a binary file prepared by a c program

A. The bits of the primitives are different in c and in Java.


Java:
       byte:              8 bits/1 byte
       short/char:     16 bits/2 bytes
       int/float:         32 bits/4 bytes
       long/double:   64 bits/8 bytes

c:
       char:              8 bits/1 byte
       short:             16 bits/2 bytes
       int/long/float:  32 bits/4 bytes
       double:          64 bits/8 bytes

B. The byte order in Unix and Windows are different. In general Unix uses the big endian and windows uses the little endian.

     

C. If a binary file is prepared by a c program and you are reading it in a java program, you need to adjust the read method to ensure that you read the right amount of bytes of that data type in c. If the binary file is prepared on a Unix machine and is read in a Windows system or vise versa, you need to adjust the byte order accordingly.


       File theFile = new File("<fileName>");
       FileInputStream fis = new FileInputStream(theFile);
       byte[] byteArray = new byte[(int)theFile.length()];
       fis.read(byteArray);
       ByteBuffer buffer = ByteBuffer.wrap(byteArray);


       //Add the following line if the binary file is prepared on a Unix machine and read on a Windows machine
       buffer.order(ByteOrder.LITTLE_ENDIAN);
       //Add this line if it is prepared on a Windows system and read on a Unix machine
       buffer.order(ByteOrder.BIG_ENDIAN);

 To read a char, instead of using buffer.getChar() which reads two bytes in java, you need to use (char)buffer.get(). 

To read a long, instead of using buffer.getLong() which reads 8 bytes in java, you need to use (new Integer(buffer.readInt())).longValue().

References:
2. How to convert byte array or char array to string in Java

----------------------------------------------------------------------------------------------------------------

                        
If you have ever asked yourself these questions, this is the book for you. What is the meaning of life? Why do people suffer? What is in control of my life? Why is life the way it is? How can I stop suffering and be happy? How can I have a successful life? How can I have a life I like to have? How can I be the person I like to be? How can I be wiser and smarter? How can I have good and harmonious relations with others? Why do people meditate to achieve enlightenment? What is the true meaning of spiritual practice? Why all beings are one? Read the book free here.

Java read from and write to a binary stream

A. Write to a binary stream

Assume that you have the following data that you would like to write to a binary stream.
      char aChar = 'T';
      long aLong = 109876L;
      int aInt = 98;
      String aString = "Nice"; //4 chars

1. Create the ByteBuffer
In java, char is 2 bytes, long is 8 bytes, int is 4 bytes. For the above data, we need in total 22 bytes.

      ByteBuffer buffer = ByteBuffer.allocate(22);

2. Put the data to the ByteBuffer
      buffer.putChar(aChar);
      buffer.putLong(aLong);
      buffer.putInt(aInt);
      buffer.put(aString.getBytes());

3. Write to the OutputStream
The code here is an example of how to write to a FileOutputStream.

      FileOutputStream fos = new FileOutputStream("<fileName>");
      fos.write(buffer.array());

B. Read from a binary stream

The sample code shows how to read from the binary file created above.

1. Create/get the InputStream
      File theFile = new File("<fileName>");
      FileInputStream fis = new FileInputStream(theFile);

2. Read data into a byte array
      byte[] byteArray = new byte[(int)theFile.length()];
      fis.read(byteArray);

3. Get the data
      ByteBuffer buffer = ByteBuffer.wrap(byteArray);
      char aChar = buffer.getChar();
      long aLong = buffer.getLong();
      int aInt = buffer.getInt();
      String aString = "";
      for (int i=0; i<4; i++) {
            sString += buffer.getChar();
      }

References:
1. How to convert byte array or char array to string in Java
2. Java how to read a binary file prepared by a c program

------------------------------------------------------------------------------------------------------------------

                        
If you have ever asked yourself these questions, this is the book for you. What is the meaning of life? Why do people suffer? What is in control of my life? Why is life the way it is? How can I stop suffering and be happy? How can I have a successful life? How can I have a life I like to have? How can I be the person I like to be? How can I be wiser and smarter? How can I have good and harmonious relations with others? Why do people meditate to achieve enlightenment? What is the true meaning of spiritual practice? Why all beings are one? Read the book free here.

Wednesday, February 26, 2014

How to convert byte array or char array to string in Java

public class ConvertTest {
      public static void main(String[] args) {
        try {
            String str = new String("Good Morning!");
            byte[] ba = str.getBytes();
            byte[] ba2 = str.getBytes("UTF-8");
            
            //Converting byte array to string
            String converted1 = new String(ba);
            String converted2 = new String(ba2, "UTF-8");
            System.out.println("converted1: "+converted1);
            System.out.println("converted2: "+converted2);
            
            char[] ca = str.toCharArray();
            
            //Converting char array to string
            String converted3 = new String(ca);
            String converted4 = String.valueOf(ca);
            System.out.println("converted3: "+converted3);
            System.out.println("converted4: "+converted4);
        } catch (UnsupportedEncodingException use) {
            System.out.println(use.getMessage());
        }
    }
}

References:
1.Java read from and write to a binary stream
2. Java how to read a binary file prepared by a c program

---------------------------------------------------------------------------------------------------------------

                        
If you have ever asked yourself these questions, this is the book for you. What is the meaning of life? Why do people suffer? What is in control of my life? Why is life the way it is? How can I stop suffering and be happy? How can I have a successful life? How can I have a life I like to have? How can I be the person I like to be? How can I be wiser and smarter? How can I have good and harmonious relations with others? Why do people meditate to achieve enlightenment? What is the true meaning of spiritual practice? Why all beings are one? Read the book free here.

Tuesday, February 25, 2014

JavaFX using cascading style sheet (CSS) to change the appearance of your GUI

Using CSS to control the appearance of the user interface in JavaFX is quite similar to using CSS to control the user interface in HTML.


Style Definitions

Create the <your file name>.css file and put it in the main directory of your JavaFX application. Each style definitions in the CSS file has a name also known as the selector, followed by the curly braces {} that defines the declaration block inside which are the rules of the style definition. Each rule is a property with a value assigned to it. If the selector of the style definition is associated with a class name, it is preceded by a dot, and is known as a class style selector. For example,

.button{
       -fx-font: 18px "Serif";
       -fx-text-fill: white;
       -fx-alignment: LEFT;
       -fx-padding: 10;
       -fx-foreground-color: #00FF99;
       -fx-background-color: #CCFF99;
}

 If the selector of a style definition is associated with a JavaFX node ID, the selector is preceded by the # sign, and is known as an ID style selector. the node ID can be set by calling the node's setID() method. For example, if you have set the node ID of your Save button to save-button, the style definition may look like this.

#save-button{
       -fx-font-size: 14px;
       -fx-font-family: "Courier New";
       -fx-text-fill: rgb(203, 128, 99);
       -fx-alignment: CENTER;
       -fx-padding: 12;
}


.root Style Class

The .root style class defines the appearance of the root node of the scene. Since all nodes in the scene are descendants of the root node, rules in the .root style class are also applied to all the other nodes in the scene. A style rule assigned to a particular node overrides the corresponding rule in the .root style class. The common rules that consistently apply to other nodes are also included in the .root style class. They can be referenced by other style definitions to ensure UI consistency. For example in the following .root style class, the -fx-base is such a property that can be used by other style definitions.

.root {
       -fx-focused-base: blue;
       -fx-background: rgb(225, 212, 205);
}

.text-field.focused {
      -fx-color: -fx-focused-base;
}


Assign a class style definition to your control

Button saveButton = new Button("Save");
saveButton.getStyleClass().add( "<the class selector of your style definition>" );


Assing an ID style definition to your control

Button saveButton = new Button("Save");
saveButton.setId( "<the ID selector of your style definition>" );


Inline styles in the code

Instead of using the style definitions in a separated .css file, you can add your styles directly in the code.

Button saveButton = new Button("Save");
saveButton.setStyle( "-fx-font-size: 14px; -fx-font-family: "Courier"; -fx-alignment: CENTER;" );
          
--------------------------------------------------------------


                        
If you have ever asked yourself these questions, this is the book for you. What is the meaning of life? Why do people suffer? What is in control of my life? Why is life the way it is? How can I stop suffering and be happy? How can I have a successful life? How can I have a life I like to have? How can I be the person I like to be? How can I be wiser and smarter? How can I have good and harmonious relations with others? Why do people meditate to achieve enlightenment? What is the true meaning of spiritual practice? Why all beings are one? Read the book free here.

Thursday, February 20, 2014

Column is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause / ORA-00979: not a GROUP BY expression / ORA-00937: not a single-group group function


This type of error occurs in one of the following situations

A. When "GROUP BY" is used in your sql, all the columns in the SELECT or in the ORDER BY clause must also be included in the  GROUP BY clause unless they are in an aggregate function such as AVG, MAX, MIN, COUNT, SUM, etc. Otherwise the system returns the erro"Column '<your column>is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause".

      For example

      SELECT c.NAME, f.FlightNo
      FROM Company c
      INNER JOIN Flight f on c.ID = f.COMID
      GROUP BY c.NAME, f.FlightNo
      ORDER BY c.NAME, f.FlightNo, f.FlightTime;

      will generate such an error  "Column 'FlightTime' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause" because the system does not know which FlightTime to use from the group for ordering the records.


      To fix the error, do one of the followings.



      1. Add the column causing the error to the GROUP BY clause

      SELECT c.NAME, f.FlightNo
      FROM Company c
      INNER JOIN Flight f on c.ID = f.COMID
      GROUP BY c.NAME, f.FlightNo,  f.FlightTime
      ORDER BY c.NAME, f.FlightNo, f.FlightTime;


      2. Make it an aggregate function if it is possible

      SELECT c.NAME, f.FlightNo
      FROM Company c
      INNER JOIN Flight f on c.ID = f.COMID
      GROUP BY c.NAME, f.FlightNo
      ORDER BY c.NAME, f.FlightNo, MIN(f.FlightTime);


      3. Remove the column from the SELECT and ORDER BY clause if it does not affect the result significantly

      SELECT c.NAME, f.FlightNo
      FROM Company c
      INNER JOIN Flight f on c.ID = f.COMID
      GROUP BY c.NAME, f.FlightNo
      ORDER BY c.NAME, f.FlightNo;

B. When the SELECT has an aggregate function as well as a ordinary column name, and the sql does not have a GROUP BY clause.

      For example 
      SELECT dep.Name, count(emp.ID)
      FROM department dep
      INNER JOIN employee emp on dep.ID = emp.depID;

      will generate such an error  "Column 'dep.Name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause" because the system does not know how to count the emp.ID. 

      To fix the error, add a GROUP BY clause to the query and put the column causing the error in the GROUP BY clause so that the system counts the emp.ID by dep.Name. All employees with the same depID are counted into one result.

      SELECT dep.Name, count(emp.ID)
      FROM department dep
      INNER JOIN employee emp on dep.ID = emp.depID
      GROUP BY dep.NAME;

-------------------------------------------------------------------------------------------------------------------------------------------------------            
                        
If you have ever asked yourself these questions, this is the book for you. What is the meaning of life? Why do people suffer? What is in control of my life? Why is life the way it is? How can I stop suffering and be happy? How can I have a successful life? How can I have a life I like to have? How can I be the person I like to be? How can I be wiser and smarter? How can I have good and harmonious relations with others? Why do people meditate to achieve enlightenment? What is the true meaning of spiritual practice? Why all beings are one? Read the book free here.

Subversion BASE, HEAD, and working copy

BASE is the revision you obtained from the repository. HEAD is the latest revision in the repository. If someone committed a change after you obtained your code from the repository, your BASE is different from the HEAD. You can do a "Update to HEAD" to make your code the same as the HEAD which is the latest revision.

If you want to see the changes you have made after you obtained your code last time, you perform "diff to BASE". If you would like to know the difference between your local code and the latest revision in the repository, you perform "diff to HEAD" or "diff to repository". After you committed your changes successfully, both the BASE and HEAD are now the same as what you have just committed.

The working copy is the local code you obtained from the repository for development. If no modification is made, it is the same as the BASE. After local changes are committed, it is the same as the HEAD. If it is neither the same as the BASE nor the same as the HEAD, a merge is needed before commit.

--------------------------------------------------------------------------------------------------------------

                        

If you have ever asked yourself these questions, this is the book for you. What is the meaning of life? Why do people suffer? What is in control of my life? Why is life the way it is? How can I stop suffering and be happy? How can I have a successful life? How can I have a life I like to have? How can I be the person I like to be? How can I be wiser and smarter? How can I have good and harmonious relations with others? Why do people meditate to achieve enlightenment? What is the true meaning of spiritual practice? Why all beings are one? Read the book free here.

Tuesday, February 18, 2014

Prototype Design Pattern

The prototype pattern is used to get a new object by cloning an existing object instead of creating a new object when creating a new object is too costly.

For example, your JTable has a TableModel that holds data which are very expensive to query from the database, to create or to get from a remote site. You would like to provide an undo function after the user finishes modifying the data, therefore you need another instance of the TableModel to hold the data before the user makes the change to the TableModel used by the JTable. You can apply the prototype pattern here to make a copy of you JTable's model instead of querying the database for all the data, recreating the data, or retrieving from the remote.

import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

//The prototype object
class MyTableModel extends DefaultTableModel {

    public MyTableModel() {
        super();
        setColumnIdentifiers(new String[]{"Name", "Value"});
    }

    //deep clone all the data to immutable, so that modification will not over write the clone
    public MyTableModel cloneModel() {
        System.out.println("Cloning...");
        MyTableModel model = new MyTableModel();

        //deep copy to the level of immutable data
        Vector data = this.getDataVector();
        Vector rowData = new Vector();
        int size = data.size();
        for (int i = 0; i < size; i++) {
            Vector originData = (Vector) data.get(i);
            for (int j = 0; j < originData.size(); j++) {
                rowData.add(originData.get(j));
            }
            model.addRow(rowData);
            rowData = new Vector();
        }

        return model;
    }
}

//The application uses the table model
class FruitInfo extends JFrame {
    private MyTableModel model;
    private MyTableModel modelClone;
    private JTable table;
   
        public FruitInfo() {
            model = new MyTableModel();
            model.addRow(new Object[]{"Apple", new Float(1.19)});
            model.addRow(new Object[]{"Banana", new Float(0.59)});

            //make a clone of the table model
            modelClone = model.cloneModel();
           
            table = new JTable();
            table.setModel(model);
           
            JScrollPane sp = new JScrollPane(table);
            add(sp);
           
            JButton save = new JButton("Save");
            save.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    if (table.getCellEditor() != null) {
                        table.getCellEditor().stopCellEditing();
                    }
                    JOptionPane.showMessageDialog(FruitInfo.this, "Data Saved!");
                }
            });
           
            JButton undo = new JButton("Undo");
            undo.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    if (table.getCellEditor() != null) {
                        table.getCellEditor().stopCellEditing();
                    }
                    System.out.println("Undo pressed!");
                   
                    //clear the table model to make it ready for importing data from modelClone
                    while (model.getRowCount() > 0){
                        model.removeRow(0);
                    }
                    Vector data = modelClone.getDataVector();
                    Vector rowData = new Vector();
                    for (int j=0; j<data.size(); j++){
                        Vector row = (Vector)data.get(j);
                        for (int r = 0; r<row.size(); r++){
                            rowData.add(row.get(r));
                        }
                        model.addRow(rowData);
                        rowData = new Vector();
                    }
                    model.fireTableDataChanged();
                }
               
            });
           
            JPanel buttonPanel = new JPanel();
            buttonPanel.add(save);
            buttonPanel.add(undo);
            add(buttonPanel, BorderLayout.SOUTH);
           
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setSize(200, 200);
            setVisible(true);
        }
    }

//The test class
public class PrototypeTest {
   
    public static void main(String[] args){
        javax.swing.SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                new FruitInfo();
            }
        });
    }
}
   
--------------------------------------------------------------------------------------------------------------       

                        
If you have ever asked yourself these questions, this is the book for you. What is the meaning of life? Why do people suffer? What is in control of my life? Why is life the way it is? How can I stop suffering and be happy? How can I have a successful life? How can I have a life I like to have? How can I be the person I like to be? How can I be wiser and smarter? How can I have good and harmonious relations with others? Why do people meditate to achieve enlightenment? What is the true meaning of spiritual practice? Why all beings are one? Read the book free here.

Friday, February 14, 2014

Builder Design Pattern

The builder pattern is used to construct a complex object by making its components one by one.

For example if you would like to build a car, you need to build the frame, the engine, the wheels, the doors, etc.


//The components or parts of a car

public interface Part {
       String name;
       float price;
}

public class Frame implements Part {
      public String getName() {
            return "Frame";
      }

      public float getPrice() {
            return 2000;
      }
}

public class Engine implements Part {
      public String getName() {
            return "Engine";
      }

      public float getPrice() {
            return 6000;
      }
}


//The car

public class Car {
      private float cost = 0;

      public void addPart(Part part) {
            cost += part.getPrice();
            System.out.println(part.getName() + " built on the car");
      }

      public void getCost() {
            return (50000 + cost);
      }
}


//The car builder

public class CarBuilder {
      private Car theCar;

      public Car buildCar() {
            theCar = new Car();
            theCar.addPart(new Frame());
            theCar.addPart(new Engine());
            System.out.println("The cost for building this car is " + theCar.getCost());
      }
}


//The Runner

public class CarBuilderDemo {
      public static void main(String[] args) {
            CarBuilder builder = new CarBuilder();
            builder.buildCar();
      }
}

---------------------------------------------------------------------------------------------------------------

                        

If you have ever asked yourself these questions, this is the book for you. What is the meaning of life? Why do people suffer? What is in control of my life? Why is life the way it is? How can I stop suffering and be happy? How can I have a successful life? How can I have a life I like to have? How can I be the person I like to be? How can I be wiser and smarter? How can I have good and harmonious relations with others? Why do people meditate to achieve enlightenment? What is the true meaning of spiritual practice? Why all beings are one? Read the book free here.

Thursday, February 13, 2014

SQL Inner Join and Outer Join

Inner Join and Outer Join are used to query information from two database tables. Using them in combination or repeatedly, you can query information from multiple tables.

For example, your organization has an artist table containing all the artists including all dancers and singers, which has a artistId column , a dancer table that has a dancerId column, and a singer table that has a singerId column.  Both the dancerId in the dancer table and the singerId in the singer table reference the artistId in the artist table.

Columns in the artist table: artistId, name, phone, address
Columns in the dancer table: dancerId, style, level
Columns in the singer table: singerId, style, level


Inner Join: Returns only those records that the joining condition matches. For example to list the names and styles of the dancers only:


SELECT a.name, b.style
FROM artist a
Inner Join dancer b on a.artistId = b.dancerId;


Left Outer Join: Returns all the records from the table or from previous Joins before the current Left Outer Join and only those records that match the joining condition from the table following the Left Outer Join. For example to list all the artists including both dancers and singers and the dancing styles of those who are dancers:


SELECT a.name, b.style as "dancing style"
FROM artist a
Left Outer Join dancer b on a.artistId = b.dancerId;


Right Outer Join is the opposite of Left Outer Join. It returns only those records that the joining condition matches from the table or previous Joins before the current Right Outer Join and all the records from the table following the Right Outer Join. For example to list the name and style of all the dancers and the sing style of those who are also singers:


SELECT a.name, b.style as "dancing style", c.style as "singing style"
FROM singer c
Right Outer Join dancer b on b.dancerId = c.singerId
Inner Join artist a on a.artistId = b.dancerId;


Full Outer Join returns all the records match as well as those don't match the joining condition from both sides of the Full Outer Join. For example to list the names, the dancing styles, and the singing styles of all the artists:


SELECT a.name, b.style as "dancing style", c.style as "singing style"
FROM artist a
Full Outer Join dancer b on a.artistId = b.dancerId 
Full Outer Join singer c on a.artistId = c.dancerId;

The Join Predicate is the part following the word "on". In the above Righ Outer Join example, the b.dancerid = c.singerId and a.artistId = b.dancerId are join predicates.

-------------------------------------------------------------------------------------------------------------------

                        
If you have ever asked yourself these questions, this is the book for you. What is the meaning of life? Why do people suffer? What is in control of my life? Why is life the way it is? How can I stop suffering and be happy? How can I have a successful life? How can I have a life I like to have? How can I be the person I like to be? How can I be wiser and smarter? How can I have good and harmonious relations with others? Why do people meditate to achieve enlightenment? What is the true meaning of spiritual practice? Why all beings are one? Read the book free here.


Wednesday, February 12, 2014

JTable does not display the value set by the setValueAt method

You programmatically set the cell value by calling setValueAt(value, row, column) on the JTable or on the DefaultTableModel and then calling either repaint() method of the JTable  or the fireTableDataChanged() method of the DefaultTableModel. To your surprise, the JTable does not display the value you just set and throws no exception.

 This situation happens if you are currently editing the cell, for example you have double clicked in the cell. You need to call <your table name>.getCellEditor().stopCellEditing() before you programmatically set the value to the cell.
          
-----------------------------------------------------------------------------------------------------------------

                        
If you have ever asked yourself these questions, this is the book for you. What is the meaning of life? Why do people suffer? What is in control of my life? Why is life the way it is? How can I stop suffering and be happy? How can I have a successful life? How can I have a life I like to have? How can I be the person I like to be? How can I be wiser and smarter? How can I have good and harmonious relations with others? Why do people meditate to achieve enlightenment? What is the true meaning of spiritual practice? Why all beings are one? Read the book free here.

JTable TableModelListener does not work consistently

It can be frustrating that some times the TableModelListener is fired and other times it is not when you click some where outside the currently editing cell. After you just entered a new value into a table cell, you immediately click the Save button, and surprisingly the new value you just entered was not saved, and you wonder why. The table model takes the modified value from the JTable only at the moment the cell stopped editing, and that is when the tableChanged method in the TableModelListener is called. Therefore, the code needs to specifically call the stopCellEditing method when you are performing other actions instead of selecting another cell in the JTable. In the above example, after you typed a string in one of the table cells and then click the Save button, you need to deliberately call the stopCellEditing method for the TableModelListener to work.

In the following sample code, you can notice the difference. If you comment out the line table.getCellEditor().stopCellEditing(); The pop-up window in the TableModelListener will not show.

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;

public class TestCode extends JFrame {
    DefaultTableModel model = new DefaultTableModel();
    JTable table = new JTable();
    public TestCode() {
        model.setColumnIdentifiers(new String[] {"Name", "Value"});
        model.addRow(new String[] {"Rose", ""});
        model.addRow(new String[] {"Peony", ""});
     
        model.addTableModelListener(new MyModelListener());
     
        table.setModel(model);
     
        JScrollPane jsp = new JScrollPane(table);
        add(jsp);
     
        JButton save = new JButton("Save");
        save.addActionListener(new MyActionListener());
        add(save, BorderLayout.SOUTH);
     
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(300,400);
        setVisible(true);
    }
 
    private class MyModelListener implements TableModelListener {
        public void tableChanged(TableModelEvent e){
            JOptionPane.showMessageDialog(TestCode.this, "Table has been modified");
        }
    }
 
    private class MyActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e){
            table.getCellEditor().stopCellEditing();
            System.out.println("Changed saved!!!!");
        }
    }
 
    public static void main(String[] args){
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TestCode();
            }
        });
    }
}

-------------------------------------------------------------------------------------------------------------

                        

If you have ever asked yourself these questions, this is the book for you. What is the meaning of life? Why do people suffer? What is in control of my life? Why is life the way it is? How can I stop suffering and be happy? How can I have a successful life? How can I have a life I like to have? How can I be the person I like to be? How can I be wiser and smarter? How can I have good and harmonious relations with others? Why do people meditate to achieve enlightenment? What is the true meaning of spiritual practice? Why all beings are one? Read the book free here.