JFormattedTextField issues - java

1) how can I set Cursor to 0 possition without using Caret or Focus wrapped into invokeLater() (confortly can be solved by using #camickr Formatted Text Field Tips), is there somebody who knows another way
2) How to reset Formatter sometimes (by raising Focus by TAB from keyboard), reset doesn't works and on focusLost (empty field) Formatter returns/reincarnated chars or String back (last know before setText("");),
Note: know code or following code is only this way, about how to reset Formatter from OTN, but their terrible search rulles ...., only code (question or answer by Jeanette???)
import java.awt.event.*;
import java.beans.*;
import java.text.ParseException;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.Document;
public class FormattedNull {
private JFormattedTextField field;
private JButton focusButton;
private JComponent createContent() {
JComponent content = new JPanel();
field = new JFormattedTextField(new Integer(55));
field.setColumns(20);
field.addPropertyChangeListener(getPropertyChangeListener());
field.getDocument().addDocumentListener(getDocumentListener());
content.add(field);
focusButton = new JButton("just something focusable");
focusButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
field.setValue(0);
field.requestFocusInWindow();
}
});
content.add(focusButton);
return content;
}
protected void maybeCommitEdit(Document document) {
try {
field.commitEdit();
} catch (ParseException e) {
// uncomment to map empty string to null
if (field.getText().length() == 0) {
field.setValue(null);
}
}
}
/*public void commitEdit() throws ParseException {
if(allowsNull() && isBlank()) {
setValue(null);
}
else {
super.commitEdit();
}
}*/
private PropertyChangeListener getPropertyChangeListener() {
PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if ("value".equals(evt.getPropertyName())) {
matchValueChanged(evt.getNewValue());
}
}
};
return propertyChangeListener;
}
protected void matchValueChanged(Object value) {
System.out.println("got new value: " + value);
}
private DocumentListener getDocumentListener() {
DocumentListener documentListener = new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) {
maybeCommitEdit(e.getDocument());
}
#Override
public void insertUpdate(DocumentEvent e) {
maybeCommitEdit(e.getDocument());
}
#Override
public void changedUpdate(DocumentEvent e) {
}
};
return documentListener;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new FormattedNull().createContent());
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
});
}
}
attached images are based on my sscce
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.text.MaskFormatter;
public class TestTest {
private JFormattedTextField myFormattedField1 = new JFormattedTextField(createFormatter("AAAAAAAAAAAA"));
private JFormattedTextField myFormattedField2 = new JFormattedTextField(createFormatter("AAAAAAAAAAAA"));
private JFormattedTextField myFormattedField3 = new JFormattedTextField(createFormatter("AAAAAAAAAAAA"));
private JFormattedTextField myFormattedField4 = new JFormattedTextField(createFormatter("AAAAAAAAAAAA"));
private JButton jb = new JButton("Reset to Default");
private JFrame frame = new JFrame("Text Test");
public TestTest() {
myFormattedField1.setText("ABCDEFGHIJKL");
myFormattedField2.setText("ABCDEFGHIJKL");
myFormattedField3.setText("ABCDEFGHIJKL");
myFormattedField4.setText("ABCDEFGHIJKL");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(150, 150);
frame.setLayout(new GridLayout(5, 0));
frame.add(jb);
frame.add(myFormattedField1);
frame.add(myFormattedField2);
frame.add(myFormattedField3);
frame.add(myFormattedField4);
jb.addActionListener(new java.awt.event.ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
myFormattedField1.setText("");
myFormattedField2.setText("");
myFormattedField3.setText("");
myFormattedField4.setText("");
}
});
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
TestTest textTest = new TestTest();
}
protected MaskFormatter createFormatter(String s) {
MaskFormatter formatter = null;
try {
formatter = new MaskFormatter(s);
} catch (java.text.ParseException exc) {
System.err.println("formatter is bad: " + exc.getMessage());
}
return formatter;
}
}

On Mac OS, the default behavior of the UI delegate, com.apple.laf.AquaTextFieldF, is similar to CaretPositionListener:
Tab or Shift-Tab: place the caret at the beginning of the field.
Click: briefly place the caret at the beginning of the field and then move it to the click point.
IMO, the CaretPositionListener does the latter much more smoothly.
The default behavior of JFormattedTextField on focus lost is COMMIT_OR_REVERT. In the example below, Tab though the first, invalid field to see the effect. The formatter can neither commit nor revert to the invalid value, so it substitutes MASK.length() spaces. This value is valid, if a little obscure.
Addendum: I've updated the code below to allow changing the setFocusLostBehavior().
Code:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.text.MaskFormatter;
/** #see http://stackoverflow.com/questions/7378821 */
public class TrashTest {
private static final String MASK = "########";
private static final String DEFAULT = "01234567";
private static final String BOGUS = "0123456";
private JFormattedTextField jtf1 = createField();
private JFormattedTextField jtf2 = createField();
private JFormattedTextField jtf3 = createField();
private JFormattedTextField jtf4 = createField();
private JButton reset = new JButton("Reset to Default");
private JComboBox combo = new JComboBox();
private JFrame frame = new JFrame("Text Test");
public TrashTest() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(150, 150);
frame.setLayout(new GridLayout(0, 1));
frame.add(reset);
frame.add(jtf1);
frame.add(jtf2);
frame.add(jtf3);
frame.add(jtf4);
frame.add(combo);
this.initFields();
reset.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
initFields();
}
});
for (Edit e : Edit.values()) {
combo.addItem(e);
}
combo.setSelectedIndex(jtf1.getFocusLostBehavior());
combo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Edit current = (Edit) combo.getSelectedItem();
jtf1.setFocusLostBehavior(current.value);
}
});
frame.pack();
frame.setVisible(true);
}
private void initFields() {
jtf1.setText(BOGUS);
jtf2.setText(DEFAULT);
jtf3.setText(DEFAULT);
jtf4.setText(DEFAULT);
}
protected JFormattedTextField createField() {
MaskFormatter formatter = null;
try {
formatter = new MaskFormatter(MASK);
} catch (java.text.ParseException e) {
e.printStackTrace(System.out);
}
JFormattedTextField jtf = new JFormattedTextField(formatter);
return jtf;
}
enum Edit {
COMMIT(JFormattedTextField.COMMIT),
COMMIT_OR_REVERT(JFormattedTextField.COMMIT_OR_REVERT),
REVERT(JFormattedTextField.REVERT),
PERSIST(JFormattedTextField.PERSIST);
private int value;
private Edit(int n) {
this.value = n;
}
public static Edit getEnum(int n) {
for (Edit e : Edit.values()) {
if (e.value == n) {
return e;
}
}
return Edit.COMMIT_OR_REVERT;
}
}
public static void main(String[] args) {
TrashTest textTest = new TrashTest();
}
}

Related

JTextField value is not updating after button click

I am new to java swing. I am creating application for patient registration using Swing. There is a button called Clear, that button should clear the input data from the text fields.When button is InputPanel.clear() set the values correctly.But it is not updating.
My classes are below.
MainWindow class create and show the GUI.
public class MainWindow extends JFrame implements ActionListener {
private static final long serialVersionUID = 1905122041950251207L;
transient TableRowSorter<PatientTableModel> sorter;
private PatientListView patientListViewPanel = new PatientListView();
private InputPanel inputPanel = new InputPanel();
private SearchCriteriaPanel searhCriteriaPanel = new SearchCriteriaPanel(this);
public void createAndShowGUI() {
ButtonPanel btnPanel = new ButtonPanel(new MainWindow());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600, 600);
sorter = new TableRowSorter<>(patientListViewPanel.getTableModel());
GridBagLayout gbl = new GridBagLayout();
this.setLayout(gbl);
GridBagConstraints gcon = new GridBagConstraints();
gcon.weightx = 1;
gcon.weighty = 5;
gcon.fill = GridBagConstraints.BOTH;
gcon.gridx = 0;
gcon.gridy = 0;
gcon.gridwidth = 11;
gcon.gridheight = 10;
gbl.setConstraints(inputPanel, gcon);
this.add(inputPanel);
gcon.gridx = 4;
gcon.gridy = 10;
gcon.gridwidth = 11;
gcon.gridheight = 5;
gbl.setConstraints(btnPanel, gcon);
this.add(btnPanel);
gcon.gridx = 0;
gcon.gridy = 22;
gcon.gridwidth = 11;
gcon.gridheight = 10;
gbl.setConstraints(searhCriteriaPanel, gcon);
this.add(searhCriteriaPanel);
gcon.gridx = 0;
gcon.gridy = 33;
gcon.gridwidth = 11;
gcon.gridheight = 10;
gbl.setConstraints(patientListViewPanel, gcon);
this.add(patientListViewPanel);
this.setVisible(true);
inputPanel.getNameText().addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
if (inputPanel.getNameText().getText().length() > 0)
btnPanel.getSaveBtn().setEnabled(true);
}
});
patientListViewPanel.getTable().addMouseListener(new java.awt.event.MouseAdapter() {
#Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
getSelectedData();
}
});
}
public MainWindow() {
super("Patient Registration");
}
#Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
switch (button.getText()) {
case "Save":
patientListViewPanel.getTableModel()
.addData(inputPanel.getData(patientListViewPanel.getTable().getRowCount()));
button.setEnabled(false);
break;
case "Clear":
inputPanel.clear();
break;
case "Search":
SearchCriteria s = new SearchCriteria(searhCriteriaPanel.getSearchNameText().getText(),
searhCriteriaPanel.getBirthYearText().getText(), searhCriteriaPanel.getMaleChkBx().isSelected(),
searhCriteriaPanel.getFemaleChkBx().isSelected());
patientListViewPanel.filter(s);
break;
default:
}
}
}
InputPanel is handle the fields and methods related to input data
public class InputPanel extends JPanel implements PropertyChangeListener {
/**
* clear fields in input panel
*/
public void clear() {
nameText.setText(" ");
phnText.setText("0");
datePickerObj.jDatePicker.getJFormattedTextField().setText("");
maleBtn.setSelected(true);
femaleBtn.setSelected(false);
adrsTxt.setText("");
statusList.setSelectedIndex(4);
}
public InputPanel() {
// fiels will be set to panel
addDataChangedListner();
isDataValid(phnText);
}
public void addDataChangedListner() {
PatientData model = new PatientData();
model.addPropertyChangeListener(this);
nameText.getDocument().addDocumentListener(new DataChangedListener(model, "name"));
phnText.getDocument().addDocumentListener(new DataChangedListener(model, "phnNumber"));
adrsTxt.getDocument().addDocumentListener(new DataChangedListener(model, "address"));
}
#Override
public void propertyChange(PropertyChangeEvent evt) {
String property = evt.getPropertyName();
String newValue = (String) evt.getNewValue();
switch (property) {
case "name":
updatedName = newValue;
break;
case "phnNumber":
updatedPhoneNumber = newValue;
break;
case "address":
updatedAddress = newValue;
break;
default:
}
}
}
Can someone help me to resolve this?
The basic functionality that you are having difficulty with is demonstrated in the following mre: (1)
import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class MainWindow extends JFrame{
private InputPanel inputPanel;
private JButton saveBtn;
public void createAndShowGUI() {
inputPanel = new InputPanel();
saveBtn = new JButton("Save");
saveBtn.setEnabled(false);
add(saveBtn, BorderLayout.SOUTH);
JButton clearButton = new JButton("Clear");
clearButton.addActionListener(e->clearInput());
add(clearButton, BorderLayout.CENTER);
add(inputPanel, BorderLayout.NORTH);
inputPanel.getNameText().addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
if (inputPanel.getNameText().getText().length() > 0) {
saveBtn.setEnabled(true);
}
}
});
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}
private void clearInput(){
inputPanel.clear();
saveBtn.setEnabled(false);
}
public MainWindow() {
createAndShowGUI();
}
public static void main(String[] args) {
new MainWindow();
}
}
class InputPanel extends JPanel {
JTextField nameText;
/**
* clear fields in input panel
*/
public void clear() {
nameText.setText(""); //use "" and not " " so text length = 0
}
public InputPanel() {
nameText = new JTextField(5);
add(nameText);
}
public JTextField getNameText() {
return nameText;
}
}
However, a better approach is to use the model to implement the change of data :
public class MainWindow extends JFrame implements PropertyChangeListener{
private InputPanel inputPanel;
private JButton saveBtn;
private final PatientData model;
public void createAndShowGUI() {
inputPanel = new InputPanel(model);
saveBtn = new JButton("Save");
saveBtn.setEnabled(false);
add(saveBtn, BorderLayout.SOUTH);
JButton clearButton = new JButton("Clear");
clearButton.addActionListener(e->clearInput());
add(clearButton, BorderLayout.CENTER);
add(inputPanel, BorderLayout.NORTH);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}
private void clearInput(){
inputPanel.clear();
}
public MainWindow() {
model = new PatientData();
model.setPropertyChangeListener(this);
createAndShowGUI();
}
#Override
public void propertyChange(PropertyChangeEvent evt) {
updateGui();
}
private void updateGui() {
if(model.getName().trim().isEmpty()){
saveBtn.setEnabled(false);
}else{
saveBtn.setEnabled(true);
}
}
public static void main(String[] args) {
new MainWindow();
}
}
class InputPanel extends JPanel implements DocumentListener{
private final JTextField nameText;
private final PatientData model;
/**
* clear fields in input panel
*/
public void clear() {
nameText.setText(""); //use "" and not " " so text length = 0
updateModel();
}
public InputPanel(PatientData model) {
this.model = model;
nameText = new JTextField("",5);
nameText.getDocument().addDocumentListener(this);
add(nameText);
}
#Override
public void changedUpdate(DocumentEvent e) {
updateModel();
}
#Override
public void removeUpdate(DocumentEvent e) {
updateModel();
}
#Override
public void insertUpdate(DocumentEvent e) {
updateModel();
}
private void updateModel() {
model.setName(nameText.getText());
}
}
class PatientData{
private String name ="";
private PropertyChangeListener listener;
public String getName() {
return name;
}
public void setPropertyChangeListener(PropertyChangeListener listener) {
this.listener = listener;
}
public void setName(String name) {
String oldName = this.name;
this.name = name;
if(listener != null) {
listener.propertyChange(new PropertyChangeEvent(this,"name", oldName, name));
}
}
}
(Test is online here)
(1) Always consider an mre when posting a question or answer.

JComboBox ActionEvent performs with multiple comboboxes?

I am performing actions for 2 combo boxes which involves in changing the background color of JLabel. Here is my code,
public class JavaApplication8 {
private JFrame mainFrame;
private JLabel signal1;
private JLabel signal2;
private JPanel s1Panel;
private JPanel s2Panel;
public JavaApplication8()
{
try {
prepareGUI();
} catch (ClassNotFoundException ex) {
Logger.getLogger(JavaApplication8.class.getName())
.log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) throws
ClassNotFoundException
{
JavaApplication8 swingControl = new JavaApplication8();
swingControl.showCombobox1();
}
public void prepareGUI() throws ClassNotFoundException
{
mainFrame = new JFrame("Signal");
mainFrame.setSize(300,200);
mainFrame.setLayout(new GridLayout(3, 0));
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
signal1 = new JLabel("Signal 1",JLabel.LEFT);
signal1.setSize(100,100);
signal1.setOpaque(true);
signal2 = new JLabel("Signal 2",JLabel.LEFT);
signal2.setSize(100,100);
signal2.setOpaque(true);
final DefaultComboBoxModel light = new DefaultComboBoxModel();
light.addElement("Red");
light.addElement("Green");
final JComboBox s1Combo = new JComboBox(light);
s1Combo.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae)
{
if(s1Combo.getSelectedIndex() == 0)
{
signal1.setBackground(Color.RED);
}
else
{
signal1.setBackground(Color.GREEN);
}
}
});
final JComboBox s2Combo1 = new JComboBox(light);
s2Combo1.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae)
{
if(s2Combo1.getSelectedIndex() == 0)
{
signal2.setBackground(Color.RED);
}
else
{
signal2.setBackground(Color.GREEN);
}
}
});
s1Panel = new JPanel();
s1Panel.setLayout(new FlowLayout());
JScrollPane ListScrollPane = new JScrollPane(s1Combo);
s1Panel.add(signal1);
s1Panel.add(ListScrollPane);
s2Panel = new JPanel();
s2Panel.setLayout(new FlowLayout());
JScrollPane List1ScrollPane = new JScrollPane(s2Combo1);
s2Panel.add(signal2);
s2Panel.add(List1ScrollPane);
mainFrame.add(s1Panel);
mainFrame.add(s2Panel);
String[] columnNames = {"Signal 1","Signal 2"};
Object[][] data = {{"1","1"}};
final JTable table = new JTable(data,columnNames);
JScrollPane tablepane = new JScrollPane(table);
table.setFillsViewportHeight(true);
mainFrame.add(tablepane);
mainFrame.setVisible(true);
}
}
When Executed, If I change the item from combo box 1, the 2nd combo box also performs the change. Where did I go wrong?
Yours is a simple solution: don't have the JComboBoxes share the same model. If they share the same model, then changes to the selected item of one JComboBox causes a change in the shared model which changes the view of both JComboBoxes.
I wold use a method to create your combo-jlabel duo so as not to duplicate code. For instance:
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class App8 extends JPanel {
private static final int COMBO_COUNT = 2;
private static final String SIGNAL = "Signal";
private List<JComboBox<ComboColor>> comboList = new ArrayList<>();
public App8() {
setLayout(new GridLayout(0, 1));
for (int i = 0; i < COMBO_COUNT; i++) {
DefaultComboBoxModel<ComboColor> cModel = new DefaultComboBoxModel<>(ComboColor.values());
JComboBox<ComboColor> combo = new JComboBox<>(cModel);
add(createComboLabelPanel((i + 1), combo));
comboList.add(combo);
}
}
private JPanel createComboLabelPanel(int index, final JComboBox<ComboColor> combo) {
JPanel panel = new JPanel();
final JLabel label = new JLabel(SIGNAL + " " + index);
label.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
label.setOpaque(true);
combo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
ComboColor cColor = (ComboColor) combo.getSelectedItem();
label.setBackground(cColor.getColor());
}
});
panel.add(label);
panel.add(combo);
return panel;
}
private static void createAndShowGui() {
App8 mainPanel = new App8();
JFrame frame = new JFrame("App8");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
enum ComboColor {
RED("Red", Color.RED),
GREEN("Green", Color.GREEN);
private String text;
private Color color;
public String getText() {
return text;
}
public Color getColor() {
return color;
}
private ComboColor(String text, Color color) {
this.text = text;
this.color = color;
}
#Override
public String toString() {
return text;
}
}

How to update the JTextField when the variable value is changed?

I have two Java(.java) files. One has a JButton and JTextField and the other has a Thread. In first Java file, I have added an ActionListener to the JButton so that, when the button is pressed, a thread (object for 2nd .java file in created and thread is initiated) runs which modifies an integer variable continuously. How to display the value of that integer variable (of 2nd .java file) in the JTextField (of 1st .java file) ?
Detection.java
package sample;
public class Detection implements Runnable
{
public String viewers;
public int count;
public void run()
{
try
{
while (true)
{
// i have written code for displaying video.
// and it say how many no. of people in the video
// the no of people is stored in a variable "count"
viewers=""+count; //storing count as string so as to display in the JTextField
}
}
catch (Exception e)
{
System.out.println("Exception: "+e);
}
}
}
UsrInterfac.java
//build using WindowBuilder eclipse juno
package sample;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class UsrInterfac
{
private JFrame frame;
private JTextField textField;
Detection dd = new Detection();
Thread th = new Thread(dd);
/**
* Launch the application.
*/
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
UsrInterfac window = new UsrInterfac();
window.frame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public UsrInterfac()
{
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize()
{
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JButton btnStartThread = new JButton("Start Thread");
btnStartThread.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
th.start();
}
});
btnStartThread.setBounds(59, 133, 117, 23);
frame.getContentPane().add(btnStartThread);
textField = new JTextField();
textField.setBounds(270, 134, 104, 20);
frame.getContentPane().add(textField);
textField.setColumns(10);
}
}
Starting from the basics, while using Swing, it is always best to use LayoutManagers, which can make your work much more easier, in comparison to using Absolute Positioning.
Whenever one needs to change something in the View from some another thread, it is always advisable to do that using EventQueue.invokeLater(...)/EventQueue.invokeAndWait(...).
This small sample program, might be able to help you get an idea, how to accomplish what you so desire :-)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ThreadCounter
{
private CustomThread cThread;
private JTextField tField;
private JButton button;
private int counter;
public ThreadCounter()
{
counter = 0;
}
private void displayGUI()
{
JFrame frame = new JFrame("Thread Counter Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
tField = new JTextField(10);
tField.setText("0");
button = new JButton("Start");
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
if (counter == 0)
{
cThread = new CustomThread(tField);
cThread.setFlagValue(true);
cThread.start();
counter = 1;
button.setText("Stop");
}
else
{
try
{
cThread.setFlagValue(false);
cThread.join();
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
counter = 0;
button.setText("Start");
}
}
});
contentPane.add(tField);
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new ThreadCounter().displayGUI();
}
});
}
}
class CustomThread extends Thread
{
private int changingVariable;
private JTextField tField;
private boolean flag = true;
public CustomThread(JTextField tf)
{
changingVariable = 0;
tField = tf;
}
public void setFlagValue(boolean flag)
{
this.flag = flag;
}
#Override
public void run()
{
while (flag)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
tField.setText(
Integer.toString(
++changingVariable));
}
});
try
{
Thread.sleep(1000);
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
}
System.out.println("I am OUT of WHILE");
}
}
Ideally you should post your code. Anyway, when you are calling the thread code, either pass the instance of the first class (object) or an instance of JTextField, so that the thread can set the new value in the text field.

Can you link values for two JFormattedTextFields?

I've got an interface with 2 JFormattedTextFields for which I need the values (not just the displayed text) to be identical. Ideally they should both be editable, with a change in one being mirrored in the other.
I started by just sharing a single Document between the two, but quickly ran into the problem that this only links the displayed text, not the underlying value. (Silly me!)
I haven't tried adding reciprocal PropertyChangeListeners for the "value" property because I would expect that to set up an infinite loop of modification.
Am I missing something? Is there some way to do this? Or am I stuck with only allowing users to edit one of the two and only having the value propagate in one direction?
Thank you!
I need the values (not just the displayed text) to be identical.
Ideally they should both be editable, with a change in one being
mirrored in the other.
use DocumentListener,
for example (only the one directions)
import java.awt.GridLayout;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class TextLabelMirror {
private JPanel mainPanel = new JPanel();
private JTextField field = new JTextField(20);
private JTextField field1 = new JTextField(20);
public TextLabelMirror() {
field.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void changedUpdate(DocumentEvent e) {
updateLabel(e);
}
#Override
public void insertUpdate(DocumentEvent e) {
updateLabel(e);
}
#Override
public void removeUpdate(DocumentEvent e) {
updateLabel(e);
}
private void updateLabel(DocumentEvent e) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
field1.setText(field.getText());
}
});
}
});
mainPanel.setLayout(new GridLayout(1, 0, 10, 0));
mainPanel.add(field);
mainPanel.add(field1);
}
public JComponent getComponent() {
return mainPanel;
}
private static void createAndShowUI() {
JFrame frame = new JFrame("TextLabelMirror");
frame.getContentPane().add(new TextLabelMirror().getComponent());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowUI();
}
});
}
}
You can use a key listener. You simply add a key listener to both fields using the below code. the reason you need the other events is it will throw errors unless you have them in the code.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class CreateGrid
{
JFrame thisframe;
JFormattedTextField jFormattedTextField1, jFormattedTextField2;
public CreateGrid()
{
GridLayout thislayout = new GridLayout(0,2);
thisframe = new JFrame();
thisframe.setLayout(thislayout);
jFormattedTextField1 = new JFormattedTextField();
jFormattedTextField2 = new JFormattedTextField();
jFormattedTextField1.addKeyListener(new KeyAdapter()
{
public void keyReleased(KeyEvent e)
{
JFormattedTextField textField = (JFormattedTextField) e.getSource();
String text = textField.getText();
jFormattedTextField2.setText(text);
}
public void keyTyped(KeyEvent e)
{
}
public void keyPressed(KeyEvent e)
{
}
});
jFormattedTextField2.addKeyListener(new KeyAdapter()
{
public void keyReleased(KeyEvent e)
{
JFormattedTextField textField = (JFormattedTextField) e.getSource();
String text = textField.getText();
jFormattedTextField1.setText(text);
}
public void keyTyped(KeyEvent e)
{
}
public void keyPressed(KeyEvent e)
{
}
});
thisframe.add(jFormattedTextField1);
thisframe.add(jFormattedTextField2);
thisframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
thisframe.setVisible(true);
thisframe.pack();
}
public static void main(String args[])
{
new CreateGrid();
}
}
I have tested this out and it works perfectly what ever you type into one field will show up in the other as you type it.

how to drag and drop files from a directory in java

I want to implement dragging and dropping of files from a directory such as someones hard drive but can't figure out how to do it. I've read the java api but it talks of color pickers and dragging and dropping between lists but how to drag files from a computers file system and drop into my application. I tried writing the transferhandler class and a mouse event for when the drag starts but nothing seems to work. Now I'm back to just having my JFileChooser set so drag has been enabled but how to drop?
Any info or point in the right direction greatly appreciated.
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
public class FileChooserDemo
extends JPanel
implements ActionListener
{
JLabel selectedFileLabel;
JList selectedFilesList;
JLabel returnCodeLabel;
public FileChooserDemo()
{
super();
createContent();
}
void initFrameContent()
{
JPanel closePanel = new JPanel();
add(closePanel, BorderLayout.SOUTH);
}
private void createContent()
{
setLayout(new BorderLayout());
JPanel NorthPanel = new JPanel();
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
JMenuItem quit = new JMenuItem("Quit");
menuBar.add(menu);
menu.add(quit);
NorthPanel.add(menu,BorderLayout.NORTH);
JPanel buttonPanel = new JPanel(new GridLayout(7,1 ));
JButton openButton = new JButton("Open...");
openButton.setActionCommand("OPEN");
openButton.addActionListener(this);
buttonPanel.add(openButton);
JButton saveButton = new JButton("Save...");
saveButton.setActionCommand("SAVE");
saveButton.addActionListener(this);
buttonPanel.add(saveButton);
JButton delete = new JButton("Delete");
delete.addActionListener(this);
delete.setActionCommand("DELETE");
buttonPanel.add(delete);
add(buttonPanel, BorderLayout.WEST);
// create a panel to display the selected file(s) and the return code
JPanel displayPanel = new JPanel(new BorderLayout());
selectedFileLabel = new JLabel("-");
selectedFileLabel.setBorder(BorderFactory.createTitledBorder
("Selected File/Directory "));
displayPanel.add(selectedFileLabel, BorderLayout.NORTH);
selectedFilesList = new JList();
JScrollPane sp = new JScrollPane(selectedFilesList);
sp.setBorder(BorderFactory.createTitledBorder("Selected Files "));
MouseListener listener = new MouseAdapter()
{
public void mousePressed(MouseEvent me)
{
JComponent comp = (JComponent) me.getSource();
TransferHandler handler = comp.getTransferHandler();
handler.exportAsDrag(comp, me, TransferHandler.MOVE);
}
};
selectedFilesList.addMouseListener(listener);
displayPanel.add(sp);
returnCodeLabel = new JLabel("");
returnCodeLabel.setBorder(BorderFactory.createTitledBorder("Return Code"));
displayPanel.add(returnCodeLabel, BorderLayout.SOUTH);
add(displayPanel);
}
public void actionPerformed(ActionEvent e)
{
int option = 0;
File selectedFile = null;
File[] selectedFiles = new File[0];
if (e.getActionCommand().equals("CLOSE"))
{
System.exit(0);
}
else if (e.getActionCommand().equals("OPEN"))
{
JFileChooser chooser = new JFileChooser();
chooser.setDragEnabled(true);
chooser.setMultiSelectionEnabled(true);
option = chooser.showOpenDialog(this);
selectedFiles = chooser.getSelectedFiles();
}
else if (e.getActionCommand().equals("SAVE"))
{
JFileChooser chooser = new JFileChooser();
option = chooser.showSaveDialog(this);
selectedFiles = chooser.getSelectedFiles();
}
// display the selection and return code
if (selectedFile != null)
selectedFileLabel.setText(selectedFile.toString());
else
selectedFileLabel.setText("null");
DefaultListModel listModel = new DefaultListModel();
for (int i =0; i < selectedFiles.length; i++)
listModel.addElement(selectedFiles[i]);
selectedFilesList.setModel(listModel);
returnCodeLabel.setText(Integer.toString(option));
}
public static void main(String[] args)
{
SwingUtilities.invokeLater
(new Runnable()
{
public void run()
{
FileChooserDemo app = new FileChooserDemo();
app.initFrameContent();
JFrame frame = new JFrame("LoquetUP");
frame.getContentPane().add(app);
frame.setDefaultCloseOperation(3);
frame.setSize(600,400);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
//frame.pack();
frame.setVisible(true);
}
});
}
}
This is my take on the idea. I've used the "traditional" drag and drop API in this example. It has some extra "paint" tweaks just to show off what you might be able to do.
This example doesn't scan folders dropped onto it, so any folder will only register as a single file, but I'm sure you can work it out
public class TestDragNDropFiles {
public static void main(String[] args) {
new TestDragNDropFiles();
}
public TestDragNDropFiles() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new DropPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DropPane extends JPanel {
private DropTarget dropTarget;
private DropTargetHandler dropTargetHandler;
private Point dragPoint;
private boolean dragOver = false;
private BufferedImage target;
private JLabel message;
public DropPane() {
try {
target = ImageIO.read(new File("target.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
setLayout(new GridBagLayout());
message = new JLabel();
message.setFont(message.getFont().deriveFont(Font.BOLD, 24));
add(message);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
protected DropTarget getMyDropTarget() {
if (dropTarget == null) {
dropTarget = new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, null);
}
return dropTarget;
}
protected DropTargetHandler getDropTargetHandler() {
if (dropTargetHandler == null) {
dropTargetHandler = new DropTargetHandler();
}
return dropTargetHandler;
}
#Override
public void addNotify() {
super.addNotify();
try {
getMyDropTarget().addDropTargetListener(getDropTargetHandler());
} catch (TooManyListenersException ex) {
ex.printStackTrace();
}
}
#Override
public void removeNotify() {
super.removeNotify();
getMyDropTarget().removeDropTargetListener(getDropTargetHandler());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (dragOver) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(new Color(0, 255, 0, 64));
g2d.fill(new Rectangle(getWidth(), getHeight()));
if (dragPoint != null && target != null) {
int x = dragPoint.x - 12;
int y = dragPoint.y - 12;
g2d.drawImage(target, x, y, this);
}
g2d.dispose();
}
}
protected void importFiles(final List files) {
Runnable run = new Runnable() {
#Override
public void run() {
message.setText("You dropped " + files.size() + " files");
}
};
SwingUtilities.invokeLater(run);
}
protected class DropTargetHandler implements DropTargetListener {
protected void processDrag(DropTargetDragEvent dtde) {
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
dtde.acceptDrag(DnDConstants.ACTION_COPY);
} else {
dtde.rejectDrag();
}
}
#Override
public void dragEnter(DropTargetDragEvent dtde) {
processDrag(dtde);
SwingUtilities.invokeLater(new DragUpdate(true, dtde.getLocation()));
repaint();
}
#Override
public void dragOver(DropTargetDragEvent dtde) {
processDrag(dtde);
SwingUtilities.invokeLater(new DragUpdate(true, dtde.getLocation()));
repaint();
}
#Override
public void dropActionChanged(DropTargetDragEvent dtde) {
}
#Override
public void dragExit(DropTargetEvent dte) {
SwingUtilities.invokeLater(new DragUpdate(false, null));
repaint();
}
#Override
public void drop(DropTargetDropEvent dtde) {
SwingUtilities.invokeLater(new DragUpdate(false, null));
Transferable transferable = dtde.getTransferable();
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
dtde.acceptDrop(dtde.getDropAction());
try {
List transferData = (List) transferable.getTransferData(DataFlavor.javaFileListFlavor);
if (transferData != null && transferData.size() > 0) {
importFiles(transferData);
dtde.dropComplete(true);
}
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
dtde.rejectDrop();
}
}
}
public class DragUpdate implements Runnable {
private boolean dragOver;
private Point dragPoint;
public DragUpdate(boolean dragOver, Point dragPoint) {
this.dragOver = dragOver;
this.dragPoint = dragPoint;
}
#Override
public void run() {
DropPane.this.dragOver = dragOver;
DropPane.this.dragPoint = dragPoint;
DropPane.this.repaint();
}
}
}
}
You need to experiment with Drag & Drop and see exactly what flavors are available when you try to drag files. If you do this in your custom TransferHandler you'll be pleasantly surprised one Flavor is the DataFlavor.javaFileListFlavor, which indicates that the item can be used simply as a List. Try it and you'll see that it works!
Note on review of your posted code, I don't see any code for your attempt at using a TransferHandler, so it is hard to say what you could be doing wrong here.
Edit 1
You seem to be trying to use a MouseListener for your drag and drop, and I'm not familiar with this usage. Can you show a reference to a tutorial that tells you to do this?
Edit 2
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class FileDragDemo extends JPanel {
private JList list = new JList();
public FileDragDemo() {
list.setDragEnabled(true);
list.setTransferHandler(new FileListTransferHandler(list));
add(new JScrollPane(list));
}
private static void createAndShowGui() {
FileDragDemo mainPanel = new FileDragDemo();
JFrame frame = new JFrame("FileDragDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class FileListTransferHandler extends TransferHandler {
private JList list;
public FileListTransferHandler(JList list) {
this.list = list;
}
public int getSourceActions(JComponent c) {
return COPY_OR_MOVE;
}
public boolean canImport(TransferSupport ts) {
return ts.isDataFlavorSupported(DataFlavor.javaFileListFlavor);
}
public boolean importData(TransferSupport ts) {
try {
#SuppressWarnings("rawtypes")
List data = (List) ts.getTransferable().getTransferData(
DataFlavor.javaFileListFlavor);
if (data.size() < 1) {
return false;
}
DefaultListModel listModel = new DefaultListModel();
for (Object item : data) {
File file = (File) item;
listModel.addElement(file);
}
list.setModel(listModel);
return true;
} catch (UnsupportedFlavorException e) {
return false;
} catch (IOException e) {
return false;
}
}
}

Categories