Rendering/Refreshing a JTable after DnD operation? - swing

I've to JTables. I drag a row from the first table and drop it to the second.
The DnD operation works fine so far, but how can easily refresh the second table after
dropping operation? I've implemented a TableModelListener, but it works only when I
double click on a line of a table.
My question: which event listener do I need to solve my problem? Any solutions or examples?
btw: the DnD operation is performing with the tranferHandler

ok here's some code:
TableExample for creating the to tables
ListHandler1 for DnD operations
SearchRenderer for updating row heights after DnD or table changings
please keep in mind that i wrote quickly. ..
Thanks and regards!
TableExample:
package GUI_Examples;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.*;
public class TableExample implements TableModelListener{
String [] title = new String [] {"Title A", "Title B"};
String [] title2 = new String [] {"Title C", "Title D"};
Object [][] data = new String [][] {{"aaaaaaaaaaaa aaaaaa aaaaaaa", "bbbbbbbb bbbb bbbbbb bbbbbb"},
{"cccccccccc cccccccc ccccccc", "ddddddd ddd dddddddd dddddd"},
{"eeeeeeeeee eeeeeeee eeeeeee", "fffffff ffff ffffff fffffff"}};
Object [][] data2 = new String [][] {{"",""}};
private JTable table;
private JTable table2;
private JFrame frame;
private DefaultTableModel model;
private DefaultTableModel model2;
private JScrollPane pane1;
private JScrollPane pane2;
private SearchRenderer1 myRenderer;
private SearchRenderer1 myRenderer2;
TableExample() {} //constructor
public JPanel createTable() {
JPanel panel = new JPanel();
//creating tables and table models
model = new DefaultTableModel(data, title);
model2 = new DefaultTableModel(data2, title2);
table = new JTable(model);
table2 = new JTable(model2);
//setting renderers
myRenderer = new SearchRenderer1();
table.setDefaultRenderer(String.class, myRenderer);
table.getColumnModel().getColumn(0).setCellRenderer(myRenderer);
table.getColumnModel().getColumn(1).setCellRenderer(myRenderer);
myRenderer2 = new SearchRenderer1();
table2.setDefaultRenderer(String.class, myRenderer2);
table2.getColumnModel().getColumn(0).setCellRenderer(myRenderer2);
table2.getColumnModel().getColumn(1).setCellRenderer(myRenderer2);
//setting sizes
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getColumnModel().getColumn(0).setPreferredWidth(60);
table.getColumnModel().getColumn(1).setPreferredWidth(60);
table2.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table2.getColumnModel().getColumn(0).setPreferredWidth(60);
table2.getColumnModel().getColumn(1).setPreferredWidth(60);
//Drag&Drop operations
table.setDragEnabled(true);
table2.setDropMode(DropMode.INSERT);
table2.setTransferHandler(new ListHandler1(model2));
pane1 = new JScrollPane(table);
pane2 = new JScrollPane(table2);
pane1.setPreferredSize(new Dimension(150,300));
pane2.setPreferredSize(new Dimension(150,300));
updateRowHeights();
updateRowHeights2();
panel.add(pane1);
panel.add(pane2);
return panel;
}
void showTable() {
//create and show frame
JPanel testPanel = createTable();
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(testPanel);
frame.pack();
frame.setVisible(true);
}//showTable
void updateRowHeights() {
for (int row = 0; row < table.getRowCount(); row++) {
int rowHeight = table.getRowHeight();
Component comp = table.prepareRenderer(table.getCellRenderer(row, 1), row, 1);
rowHeight = Math.max(rowHeight, comp.getPreferredSize().height);
table.setRowHeight(row, rowHeight);
}
}
void updateRowHeights2() {
for (int row = 0; row < table2.getRowCount(); row++) {
int rowHeight = table2.getRowHeight();
Component comp2 = table2.prepareRenderer(table2.getCellRenderer(row, 1), row, 1);
rowHeight = Math.max(rowHeight, comp2.getPreferredSize().height);
table2.setRowHeight(row, rowHeight);
}
}
public static void main(String[] args) {
TableExample example = new TableExample();
example.showTable();
}//main
#Override
public void tableChanged(TableModelEvent e) {
updateRowHeights();
updateRowHeights2();
}
}//TableExample
ListHandler
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import javax.swing.TransferHandler;
import javax.swing.table.DefaultTableModel;
public class ListHandler1 extends TransferHandler {
DefaultTableModel model = new DefaultTableModel();
ListHandler1(DefaultTableModel tableModel) {
this.model=tableModel;
} //constructor
/**
*
*/
private static final long serialVersionUID = 1L;
/* canImport: This method tests suitability of a drop operation. Here we filter out the clipboard paste operations
* and allow only String drop operations. If the method returns false, the drop operation is cancelled.(non-Javadoc)
* #see javax.swing.TransferHandler#canImport(javax.swing.TransferHandler.TransferSupport)
*/
public boolean canImport(TransferSupport support) {
if (!support.isDrop()) {
return false;
}
return support.isDataFlavorSupported(DataFlavor.stringFlavor);
}
/*The importData() method transfers the data from the clipboard or from the drag and drop operation to the drop location.
* (non-Javadoc)
* #see javax.swing.TransferHandler#importData(javax.swing.TransferHandler.TransferSupport)
*/
public boolean importData(TransferSupport support) {
if (!canImport(support)) {
return false;
}
Transferable transferable = support.getTransferable(); //The Transferable is the class, where the data is bundled.
String line;
try {
line = (String) transferable.getTransferData(DataFlavor.stringFlavor); //We retrieve our data.
} catch (Exception e) {
return false;
}
String item [] = line.split("\t");
model.addRow(new Object[]{item[0],item[1]});
return true;
}
}
SearchRenderer:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class SearchRenderer1 extends JTextArea implements TableCellRenderer {
private static final long serialVersionUID = 1L;
public SearchRenderer1() {
setLineWrap(true);
setWrapStyleWord(true);
} //constructor
public Component getTableCellRendererComponent (JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column ) {
this.setText((String)value);
//for update row height
this.setSize(table.getColumnModel().getColumn(column).getWidth(),Short.MAX_VALUE);
if (isSelected) {
this.setBackground(new java.awt.Color(255, 240, 200));
}
else {
this.setBackground(new java.awt.Color(255, 255, 255));
}
return this;
}//getTableCellRendererComponent
}

Related

Getting null / empty JtextArea

I crated a Frame which have a panel inside it and the panel have a textarea inside it. Now i created a constructor which makes the frame visible for some time and after that it is set as invisible. Time for which it is visible it shows some massage.
When i run the constructor code inside the main method of outputDisplay class it shows the text massage
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.Timer;
public class OutputDisplay {
static JFrame frame;
JPanel panel;
JTextArea area;
Font font;
public void timer(int time){
Timer timer = new Timer(time, new ActionListener(){
public void actionPerformed(ActionEvent e){
frame.setVisible(false);
}
});
timer.start();
timer.setRepeats(false);
}
OutputDisplay(String ip,int time) throws InterruptedException{
frame = new JFrame("Warning");
frame.setLocation(400, 220);
panel = new JPanel();
area = new JTextArea();
font = new Font("Aharoni", Font.BOLD, 16);
area.setFont(font);
area.setForeground(Color.RED);
area.setSize(200, 200);
int j=0;
String[] t = {ip};
for(int i=0;i<t.length;i++){
area.append(t[i]+"\n");
}//for
panel.add(area);
panel.setLayout(new BoxLayout(panel,BoxLayout.Y_AXIS));
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.pack();
frame.setSize(600, 200);
frame.setVisible(true);
Thread.sleep(time);
j++;
if(j==1){
frame.setVisible(false);
}//if
frame.setResizable(false);
}//constructor
OutputDisplay(String dialogue,String path,int time) throws InterruptedException{
frame = new JFrame("Warning");
frame.setLocation(400, 220);
panel = new JPanel();
area = new JTextArea();
font = new Font("Aharoni", Font.BOLD, 16);
area.setFont(font);
area.setForeground(Color.MAGENTA);
area.setSize(200, 200);
int j=0;
String[] t = {dialogue};
for(int i=0;i<t.length;i++){
area.append(t[i]+"\n");
}//for
panel.add(area);
panel.setLayout(new BoxLayout(panel,BoxLayout.Y_AXIS));
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.pack();
frame.setSize(500, 200);
frame.setVisible(true);
Thread.sleep(time);
j++;
if(j==1){
frame.setVisible(false);
}//if
frame.setResizable(false);
}//constructor
OutputDisplay(String dialogue) throws InterruptedException{
frame = new JFrame("Report");
frame.setLocation(400, 220);
panel = new JPanel();
area = new JTextArea();
font = new Font("Aharoni", Font.BOLD, 16);
area.setFont(font);
area.setForeground(Color.BLUE);
area.setSize(200, 200);
String[] t = {dialogue};
for(int i=0;i<t.length;i++){
area.append(t[i]+"\n");
}//for
panel.add(area);
panel.setLayout(new BoxLayout(panel,BoxLayout.Y_AXIS));
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.pack();
frame.setSize(600, 600);
frame.setVisible(true);
frame.setResizable(false);
}//constructor
public OutputDisplay() {
}//no arg
public void dialogue (String massage) throws InterruptedException{
frame = new JFrame("Massage");
frame.setLocation(400, 220);
JPanel panel = new JPanel();
JTextArea area = new JTextArea();
Font font = new Font("Aharoni", Font.BOLD, 16);
area.setFont(font);
area.setForeground(Color.GREEN);
area.setSize(200, 200);
int j=0;
String[] t = {massage};
for(int i=0;i<t.length;i++){
area.append(t[i]+"\n");
}//for
panel.add(area);
panel.setLayout(new BoxLayout(panel,BoxLayout.Y_AXIS));
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.pack();
frame.setSize(400, 100);
frame.setVisible(true);
Thread.sleep(8*1000);
j++;
if(j==1){
frame.setVisible(false);
}//if
frame.setResizable(false);
}//dialogue
static void warningPopUp (String massage){
JOptionPane.showMessageDialog(null, massage);
}//dialogue
public static void main(String[] args){
new OutputDisplay("We are checking for account validation"+"\n"
+ "If user id and password matches then we will goto websites for updation. " +"\n"
+ "You will get a complete report once we are done", 4*1000);
}//main
}//OutputDisplay
Don't call Thread.sleep(...) on the Swing EDT as that just puts your whole GUI to sleep.
Do use a Swing Timer instead.
Do Google and search this site for similar questions.
Please check out Lesson: Concurrency in Swing
Also check out the Swing Tutorials
Edit
You're still using Thread.sleep, again you shouldn't use it, but instead should use a Timer. Also, never set a JTextArea's size or preferred size ever. Do this and the scrollbars of your JScrollPane won't work. Instead, set its rows and columns.
import java.awt.Color;
import java.awt.Font;
import java.awt.Dialog.ModalityType;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class TimeLimitedDialogTester {
private static final int EB_GAP = 25;
private JPanel mainPanel = new JPanel();
public TimeLimitedDialogTester() {
mainPanel.add(new JButton(new ShowDialogAction("Show Dialog")));
mainPanel.setBorder(BorderFactory.createEmptyBorder(EB_GAP, 2 * EB_GAP, 2 * EB_GAP, 2 * EB_GAP));
}
public JPanel getMainPanel() {
return mainPanel;
}
#SuppressWarnings("serial")
private class ShowDialogAction extends AbstractAction {
public ShowDialogAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
Window mainWin = SwingUtilities.getWindowAncestor(mainPanel);
int seconds = 5;
String dialogTitle = "WARNING";
String text = "We are checking for account validation. If user id and password matches then we"
+ " will go to websites for updating. You will get a complete report once we are done.";
TimeLimitedDialog timeLimitedDialog = new TimeLimitedDialog(mainWin, seconds, dialogTitle, text);
timeLimitedDialog.dialogShow();
}
}
private static void createAndShowGui() {
TimeLimitedDialogTester timeLimitedDialog = new TimeLimitedDialogTester();
JFrame frame = new JFrame("TimeLimitedDialog");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(timeLimitedDialog.getMainPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class TimeLimitedDialog {
private static final int ROWS = 6;
private static final int COLS = 30;
private static final Color FG = Color.green.darker().darker();
private JDialog dialog;
private JTextArea displayArea = new JTextArea(ROWS, COLS);
private int seconds;
public TimeLimitedDialog(Window mainWin, int seconds, String dialogTitle, String text) {
displayArea.setWrapStyleWord(true);
displayArea.setLineWrap(true);
displayArea.setFocusable(false);
displayArea.setText(text);
displayArea.setForeground(FG);
displayArea.setFont(displayArea.getFont().deriveFont(Font.BOLD));
this.seconds = seconds;
dialog = new JDialog(mainWin, dialogTitle, ModalityType.APPLICATION_MODAL);
dialog.add(new JScrollPane(displayArea));
dialog.pack();
dialog.setLocationRelativeTo(mainWin);
}
public void dialogShow() {
new Timer(seconds * 1000, new TimerListener()).start();
dialog.setVisible(true);
}
private class TimerListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (dialog != null && dialog.isVisible()) {
dialog.dispose();
}
((Timer) e.getSource()).stop();
}
}
}

I'm able to update the TableModel using setValueAt() but changes are not visible in the Table

I'm able to update the TableModel using setValueAt() but changes are not visible in the Table
below is the code:
import javax.swing.JFrame;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import java.awt.Dimension;
import java.awt.GridLayout;
public class TableFTFEditDemo extends JPanel {
private boolean DEBUG = true;
JTable table;
MyTableModel tableModel=new MyTableModel();
public TableFTFEditDemo() {
super(new GridLayout(1,0));
table = new JTable(tableModel);
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);
//Set up stricter input validation for the integer column.
table.setDefaultEditor(Integer.class,
new IntegerEditor(0, 100));
//If we didn't want this editor to be used for other
//Integer columns, we'd do this:
//table.getColumnModel().getColumn(3).setCellEditor(
// new IntegerEditor(0, 100));
//Add the scroll pane to this panel.
add(scrollPane);
}
class MyTableModel extends AbstractTableModel {
private String[] columnNames ;
private Object[][] data;
MyTableModel(){
columnNames=new String[] {"First Name","Last Name","Sport","# of Seaters","Vegetarian","blank"};
data=new Object[][] {
{"Kathy", "Smith",
"Snowboarding", new Integer(5), new Boolean(false),"sdf"},
{"John", "Doe",
"Rowing", new Integer(3), new Boolean(true),"reytry"},
{"Sue", "Black",
"Knitting", new Integer(2), new Boolean(false),"wwttu"},
{"Jane", "White",
"Speed reading", new Integer(20), new Boolean(true),"yuiyio"},
{"Joe", "Brown",
"Pool", new Integer(10), new Boolean(false),"ertey"}
};
}
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
return data.length;
}
public String getColumnName(int col) {
return columnNames[col];
}
public Object getValueAt(int row, int col) {
return data[row][col];
}
/*
* 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.
*/
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
public boolean isCellEditable(int row, int col) {
//Note that the data/cell address is constant,
//no matter where the cell appears onscreen.
if (col < 2) {
return false;
} else {
return true;
}
}
public void setValueAt(Object value, int row, int col) {
if (DEBUG) {
System.out.println("Setting value at " + row + "," + col
+ " to " + value
+ " (an instance of "
+ value.getClass() + ")");
}
data[row][col] = value;
this.fireTableCellUpdated(row,col);
if (DEBUG) {
System.out.println("New value of data:");
printDebugData();
}
}
private void printDebugData() {
int numRows = getRowCount();
int numCols = getColumnCount();
for (int i=0; i < numRows; i++) {
System.out.print(" row " + i + ":");
for (int j=0; j < numCols; j++) {
System.out.print(" " + data[i][j]);
}
System.out.println();
}
System.out.println("--------------------------");
}
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("TableFTFEditDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
TableFTFEditDemo newContentPane = new TableFTFEditDemo();
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.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
void runtable(){
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
tableModel.setValueAt(new Integer(5),2,5);
((AbstractTableModel)table.getModel()).fireTableCellUpdated(2,5);
}
});
}
/** using this to call setValueAt from other classes*/
public void setValueAt1(Object value, int row, int col) {
table.setValueAt(new Integer(5),row,col);
((AbstractTableModel)table.getModel()).fireTableCellUpdated(row,col);
}
}
PS: the code is taken frm oracle' example..i just want to knw how to reflect the changes made in tablemodel in the table.
Your code works as expected, just you do not actually call setValueAt() on your model. Your runtable() method where you do is never invoked.
To verify, change createAndShowGUI() to return the newContentPane and use the following main:
static TableFTFEditDemo instance;
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
instance = createAndShowGUI();
}
});
Thread.sleep(5000);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
instance.tableModel.setValueAt(5, 2, 5);
}
});
}
After the programmed five second delay, the value in column 2 row five will change from "wwtu" into "5".

may i know why it is not reading the declaration?

Im writing the content of text field to a text file:
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.SwingUtilities;
import java.io.FileNotFoundException;
import java.util.Formatter;
import javax.swing.*;
import java.util.*;
import java.io.*;
public class Payroll extends JFrame implements ActionListener{
private JButton btn1;
private JButton btn2;
private JButton btnadd;
// initialize the lbl with caption name is employee information.
JLabel lbl = new JLabel("Nilai University Payroll System");
public Payroll(){
super("Nilai University Payroll System");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
JLabel lblid,lblname,lblrank,lblclass,lbltype,lblpay;
JTextField txtid,txtname,txtrank,txtclass,txtEmployeeClass,txtEmployeeType;
JRadioButton rb1,rb2,rb3,rb4,rb5;
lbl.setBounds(200,50,500,100);
lbl.setHorizontalAlignment(lbl.CENTER );
lblid = new JLabel("Employee ID: ");
lblname = new JLabel("Employee Name: ");
lblrank = new JLabel("Employee Rank: ");
lblclass = new JLabel("Employee Class: ");
lbltype = new JLabel("Class Type: ");
lblpay = new JLabel("Employee Pay Rate: ");
// initialize all the label which are declared in the example above with its caption name
lblid.setBounds(300,140,100,20);
lblname.setBounds(300,180,100,20);
lblrank.setBounds(300,220,100,20);
lblclass.setBounds(300,260,100,20);
lbltype.setBounds(300,300,100,20);
lblpay.setBounds(300,340,100,20);
// add all the label on the frame
add(lblid);
add(lblname);
add(lblrank);
add(lblclass);
add(lbltype);
add(lblpay);
// initialize the text field with size
txtid=new JTextField(15);
txtname=new JTextField(15);
txtclass=new JTextField(15);
txtEmployeeClass=new JTextField(15);
txtEmployeeType=new JTextField(15);
// set a particular position on a screen with set bounds constructor
txtid.setBounds(400,140,100,20);
txtname.setBounds(400,180,100,20);
txtclass.setBounds(400,220,100,20);
txtEmployeeClass.setBounds(400,260,100,20);
txtEmployeeType.setBounds(400,300,100,20);
// add text field on a Frame
add(txtid);
add(txtname);
add(txtclass);
add(txtEmployeeClass);
add(txtEmployeeClass);
// initialize radio button with its caption
rb1 = new JRadioButton("1. Excellent");
rb2 = new JRadioButton("2. Good");
rb3 = new JRadioButton("3. Average");
rb4 = new JRadioButton("4. Fair");
rb5 = new JRadioButton("5. Poor");
// set a particular position on a Frame
rb1.setBounds(400,220,100,20);
rb2.setBounds(500,220,100,20);
rb3.setBounds(600,220,100,20);
rb4.setBounds(700,220,100,20);
rb5.setBounds(800,220,100,20);
// add button on a frame
add(rb1);
add(rb2);
add(rb3);
add(rb4);
add(rb5);
btnadd = new JButton("Add Employee");
btnadd.setToolTipText("Click this button to add employee details to a text file.");
btnadd.setBounds(400,320,150,20);
add(btnadd);
btnadd.addActionListener(this);
btnadd.setActionCommand("Add");
}
private BufferedWriter output;
public void actionPerformed(ActionEvent e){
String cmd = e.getActionCommand();
if(cmd.equals("Add"))
{
output.write("ID: "+txtid.getNume()+"\n");
}
}
public void WriteFile(){
try {
output = new BufferedWriter(new FileWriter("E:/EC3307/eclipse/Payroll.txt",true));
output.newLine();
output.close();
}
catch(IOException e)
{
System.out.println("There was a problem:" + e);
}
}
public static void main(String args[]){
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run()
{
Payroll f1=new Payroll();
// set frame size
f1.setSize(1000,600);
// set frame visible true
f1.setVisible(true);
}
});
}
}
The problem is that txtid is a local variable of your Payroll constructor and not a member of the Payroll class. Simply declare txtid as variable of your Payroll class and this will allow to access it in your actionPerformed method.
Declare txtid outside of Payroll() constructor

Why does part of my RichJLabel text look covered/hidden?

I've been reading the Swing Hacks book and have used some of their code for the RichJLabel part. I understand what the code does, but not why some of the word is covered or looks hidden. It's not that it's not drawing all of the text because even half of the 'a' in horizontal is missing.
//imported libraries for the GUI
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.*;
import java.awt.Toolkit;
import java.awt.Dimension;
import java.awt.Container;
import java.awt.BorderLayout;
import java.awt.*;
//Rich JLabel
import java.awt.GraphicsEnvironment;
import java.awt.Graphics2D;
import java.awt.FontMetrics;
import java.awt.RenderingHints;
import java.awt.font.*;
import javax.swing.ListSelectionModel;
import java.awt.Color;
import java.awt.Font;
public class nameInterfaceOne
{
//Declared components
static JFrame frame;
static JPanel TotalGUI, northP, southP, eastP, centerP, westP;
static JButton buttons;
//Frame method
public nameInterfaceOne()
{
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} //For a different look & feel, change the text in the speech marks
catch (ClassNotFoundException e) {}
catch (InstantiationException e) {}
catch (IllegalAccessException e) {}
catch (UnsupportedLookAndFeelException e) {}
frame = new JFrame("Interface");
frame.setExtendedState(frame.NORMAL);
frame.getContentPane().add(create_Content_Pane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500); //Size of main window
frame.setVisible(true);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
// gets & sets frame size/location
int fw = frame.getSize().width;
int fh = frame.getSize().height;
int fx = (dim.width-fw)/2;
int fy = (dim.height-fh)/2;
//moves the frame
frame.setLocation(fx, fy);
}
public JPanel create_Content_Pane()
{
TotalGUI = new JPanel();
TotalGUI.setLayout(new BorderLayout(5,5)); //set layout for the Container Pane
northP = new JPanel();
northP.setBorder(new TitledBorder(new EtchedBorder(), "Label"));
TotalGUI.add(northP, BorderLayout.NORTH);
RichJLabel label = new RichJLabel("Horizontal", 1);
label.setLeftShadow(1,1,Color.white);
label.setRightShadow(1,1,Color.gray);
label.setForeground(Color.black);
label.setFont(label.getFont().deriveFont(20f));
Box top = Box.createHorizontalBox();
top.add(Box.createHorizontalStrut(10));
top.add(label);
top.add(Box.createHorizontalStrut(10));
northP.add(top);
//EAST Panel
eastP = new JPanel();
eastP.setBorder(new TitledBorder(new EtchedBorder(), "Boxes"));
TotalGUI.add(eastP, BorderLayout.EAST);
Box right = Box.createVerticalBox();
right.add(Box.createVerticalStrut(20));
right.add(new JLabel("EAST SIDE!"));
eastP.add(right);
//WEST Panel
westP = new JPanel();
westP.setBorder(new TitledBorder(new EtchedBorder(), "Buttons"));
TotalGUI.add(westP, BorderLayout.WEST);
Box left = Box.createVerticalBox();
left.add(Box.createVerticalStrut(10));
ButtonGroup JbuttonGroup = new ButtonGroup();
JButton buttons;
JbuttonGroup.add(buttons = new JButton("One"));
buttons.setToolTipText("This is Button One");
left.add(buttons);
left.add(Box.createVerticalStrut(10));
JbuttonGroup.add(buttons = new JButton("Two"));
buttons.setToolTipText("This is Button Two");
left.add(buttons);
left.add(Box.createVerticalStrut(10));
JbuttonGroup.add(buttons = new JButton("Three"));
buttons.setToolTipText("This is Button Three");
left.add(buttons);
left.add(Box.createVerticalStrut(10));
westP.add(left);
TotalGUI.setOpaque(true);
return(TotalGUI);
}
//Main method calling a new object of
public static void main(String[] args)
{
new nameInterfaceOne();
}
}
//RICH JLABEL CLASS
class RichJLabel extends JLabel
{
private int tracking;
public RichJLabel(String text, int tracking) {
super(text);
this.tracking = tracking;
}
private int left_x, left_y, right_x, right_y;
private Color left_color, right_color;
public void setLeftShadow(int x, int y, Color color) {
left_x = x;
left_y = y;
left_color = color;
}
public void setRightShadow(int x, int y, Color color) {
right_x = x;
right_y = y;
right_color = color;
}
public Dimension getPreferredSize()
{
String text = getText();
FontMetrics fm = this.getFontMetrics(getFont());
int w = fm.stringWidth(text);
w += (text.length())*tracking;
w += left_x + right_x;
int h = fm.getHeight();
h += left_y + right_y;
return new Dimension(w,h);
}
public void paintComponent(Graphics g) {
((Graphics2D)g).setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
char[] chars = getText().toCharArray();
FontMetrics fm = this.getFontMetrics(getFont());
int h = fm.getAscent();
int x = 0;
for(int i=0; i<chars.length; i++)
{
char ch = chars[i];
int w = fm.charWidth(ch) + tracking;
g.setColor(left_color);
g.drawString(""+chars[i],x-left_x,h-left_y);
g.setColor(right_color);
g.drawString(""+chars[i],x+right_x,h+right_y);
g.setColor(this.getForeground());
g.drawString(""+chars[i],x,h);
x+=w;
}
((Graphics2D)g).setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
} // end paintComponent()
}
Thank you in advance for any help :)
Empirically, the problem disappears when adding the label directly to the (default) FlowLayout of northP.
northP.add(label);
Addendum: An alternative is to override getMaximumSize(), as suggested in How to Use BoxLayout: Specifying Component Sizes.
#Override
public Dimension getMaximumSize() {
return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
}

jgoodies binding: using a JTextField with a formatted number?

I am trying to bind a JTextField to a bean's field that is a double using JGoodies Binding:
JTextField myJTextField = ...
BeanAdapter adapter = ...
Bindings.bind(myJTextField,
ConverterFactory.createStringConverter(adapter.getValueModel("amplitude"),
new DecimalFormat("0.00000")));
This works, at least in the bean → JTextField direction. In the JTextField → bean direction, it has one hitch: if I start typing in the JTextField it takes my update immediately after the first digit after the decimal point, messes up the JTextField focus, and tweaks my JTextField value.
(the problem seems to come from trying to adapt a GUI's String to a model's double)
How do I fix this????
sample program that demonstrates this:
package com.example.test.gui;
import java.awt.GridLayout;
import java.beans.PropertyChangeListener;
import java.text.DecimalFormat;
import java.util.Hashtable;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import com.jgoodies.binding.adapter.Bindings;
import com.jgoodies.binding.adapter.BoundedRangeAdapter;
import com.jgoodies.binding.beans.BeanAdapter;
import com.jgoodies.binding.beans.ExtendedPropertyChangeSupport;
import com.jgoodies.binding.value.ConverterFactory;
public class FloatPointBinding {
public static class MyModel {
private int x;
final private ExtendedPropertyChangeSupport changeSupport =
new ExtendedPropertyChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener x) {
this.changeSupport.addPropertyChangeListener(x);
}
public void removePropertyChangeListener(PropertyChangeListener x) {
this.changeSupport.removePropertyChangeListener(x);
}
static private int clip(int a)
{
return Math.min(Math.max(a, -32768), 32767);
}
static private int d2i(double a) {
return clip((int) Math.floor(a*32768 + 0.5));
}
static private double i2d(int a) {
return (clip(a)/32768.0);
}
public void setXCount(int x) {
int oldX = this.x;
int newX = x;
this.x=newX;
this.changeSupport.firePropertyChange("x", i2d(oldX), i2d(newX));
this.changeSupport.firePropertyChange("XCount", oldX, newX);
}
public void setX(double x) { setXCount(d2i(x)); }
public double getX() { return i2d(this.x); }
public int getXCount() { return this.x; }
}
public static class MyView extends JFrame
{
public MyView(MyModel model, String title)
{
super(title);
JTextField jtf = new JTextField();
JSlider jsl = new JSlider();
jsl.setMinimum(-32768);
jsl.setMaximum(32767);
jsl.setMajorTickSpacing(4096);
jsl.setPaintTicks(true);
Hashtable labelTable = new Hashtable();
labelTable.put( new Integer( -32768 ), new JLabel("-1") );
labelTable.put( new Integer( 0 ), new JLabel("0") );
labelTable.put( new Integer( 32767 ), new JLabel("1") );
jsl.setLabelTable( labelTable );
jsl.setPaintLabels(true);
setLayout(new GridLayout());
add(jsl);
add(jtf);
BeanAdapter adapter = new BeanAdapter(model, true);
Bindings.bind(jtf,
ConverterFactory.createStringConverter(adapter.getValueModel("x"),
new DecimalFormat("0.#####")));
jsl.setModel(new BoundedRangeAdapter(adapter.getValueModel("XCount"), 0, -32768, 32767));
}
}
public static void main(String[] args)
{
MyModel model = new MyModel();
MyView view = new MyView(model, "FloatPointBinding");
view.pack();
view.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
view.setVisible(true);
}
}
I am not sure if this is what you are trying to solve, but if you change the binding to only commit on focus lost you shouldn't have that issue anymore. Just specify true as the third argument to the bind method below:
Bindings.bind(jtf,
ConverterFactory.createStringConverter(adapter.getValueModel("x"),
new DecimalFormat("0.#####")),
true);