My goal is to write something that is visible to the user in the JTextField and to display this text in the console.
As of now, the JTextField is accepting text but nothing shows. No cursor, no text.
I've tried using textfield.setEditable(true), textfield.setEnable(true) and different fore and background colors but nothing happens.
Curiously I can use textField.setText("Random text") and it shows, but I cant delete it or edit this when the program is running and it's not included in the outputs from getText().
This is the program :
import acm.program.*;
import java.awt.Color;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class TextFieldTest extends ConsoleProgram implements SomeConstants {
public void init() {
setSize(APPLICATION_WIDTH, APPLICATION_HEIGHT);
textField = new JTextField(20);
add(textField, SOUTH);
textField.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == textField)
println("Hi, " + textField.getText());
}
private JTextField textField;
}
If you're working with acm.program.ConsoleProgram, you may need to use Java SE 5 (version 1.5), as suggested here.
Addendum: As #Tor comments, java.awt.TextField may be acceptable under later versions of the JRE.
Related
I have a JComboBox that is editable. When the user enters a new item, I want that added to the list and display it as the selected item. I am able to add it to the list but I cannot seem to make it display as the selected item. By default I display an empty string ("") which is what the user would edit to add the new item.
public class EventComboBoxListener implements ActionListener {
private JComboBox<String> eventBox=null;
public EventComboBoxListener(JComboBox<String> event_) {
eventBox=event_;
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Selected: " + eventBox.getSelectedItem());
System.out.println(", Position: " + eventBox.getSelectedIndex());
if (eventBox.getSelectedIndex() < 0) {
eventBox.addItem(eventBox.getSelectedItem().toString());
eventBox.setSelectedItem(eventBox.getSelectedItem().toString());
}
}
}
It doesn't make sense to me that I have to use setSelectedItem with the getSelectedItem. That it does not work is no surprise but I don't know what else to do. The newly added item shows up in the list as it should but how do I make it the selected item in the display at the same time? I can select it after but that should not be necessary.
Added MVCE:
Main
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
public class Test {
public static void main(String[] args) {
String[] list= {"","A","B","C"};
TestTableModel model=new TestTableModel(null,new String[] {"col1","col2"});
JTable table=new JTable(model);
JDialog dialog=new JDialog();
JScrollPane scroller=new JScrollPane(table);
JComboBox<String> box=new JComboBox<String>(list);
box.setEditable(true);
box.setSelectedIndex(0);
box.addActionListener(new EventComboBoxListener(box));
JTextField field=new JTextField();
field.setPreferredSize(new Dimension(75,30));
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setLayout(new FlowLayout());
dialog.setSize(new Dimension(400,100));
dialog.add(scroller);
dialog.pack();
dialog.setVisible(true);
table.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(box));
table.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(field));
model.insertRow(0,new Object[] {"","placeholder"});
}
}
TestTableModel class
import javax.swing.table.DefaultTableModel;
public class TestTableModel extends DefaultTableModel {
/**
*
*/
private static final long serialVersionUID = 1L;
public TestTableModel(Object[][] data_,String[] columnNames_) {
super(data_,columnNames_);
}
}
First of all some comments about the MCVE (since you will be including one with every question in the future).
We expect the code so be in a single source file so we can easily copy/paste compile and test. We don't want 3 files lying around on our machine that we need clean up after testing.
Only relevant code directly related to the problem should be included. Why do you have the TestTableModel class. Are the "column names" relevant to the problem? The point is always test your MCVE using standard JDK classes when possible.
Regarding the EventComboListener class. Again, this can be added to the combo box by using and annoymouse inner class or a lambda. This keeps the code in a single class.
The newly added item shows up in the list as it should but how do I make it the selected item in the display at the same time?
I found that playing with your MCVE the ActionListener of the combo box is invoked at different times.
So my suggestion is to add the ActionListener to the editor of the combo box. Then we know for sure the ActionListener is only invoked when you press the Enter key. Once you press the Enter key the editor is stopped and the value is saved to the model.
So the logic would be something like:
//box.addActionListener(new EventComboBoxListener(box));
ComboBoxEditor editor = box.getEditor();
JTextField textField = (JTextField)editor.getEditorComponent();
textField.addActionListener( new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
String item = textField.getText();
DefaultComboBoxModel model = (DefaultComboBoxModel)box.getModel();
if (model.getIndexOf(item) == -1)
{
box.addItem(item);
box.setSelectedIndex( box.getItemCount() - 1 );
}
}
});
So the trick is to set the select index (not the selected item). But first the logic checks to make sure the item has not already been added to the combo box.
I want to have a checkbox with multi-line text and I want to disable it sometimes.
Simple JCheckBox works fine and gets disabled, but it's not multiline.
Putting <html>line1<br>line2</html> provides correct size and layout, but when I disable the control, only the checkbox itself is grayed, the text remains black.
I know I can change the HTML text color to gray, but this will not work for the "Classic Windows" look-and-feel where disabled text should rendered as "sunken". Or, actually, it will work, but the appearance will differ from other disabled controls nearby, which is not good.
I can create a simple JCheckBox containing the first line of text and a JLabel with the second line and disable them simultaneously, but clicking the second line (the JLabel) doesn't activate the checkbox, and clicking the checkbox displays the keyboard focus only around the first line which confuses the user.
Is it possible to have a checkbox and its label as separate controls and have some kind of link between them, as in HTML? Probably I would be able to cook something from this.
Is it possible to subclass JButton and override something there, for example, to change the way the focus rectangle is drawn? The rectangle is drawn by com.sun.java.swing.plaf.windows.WindowsButtonUI but I'm kinda afraid of subclassing that class because it's too deep in the standard library and my application may break with a new JRE.
EDIT 04.02.2015: The above applies to Java 1.6. In Java 1.7 and higher, disabling a multi-line checkbox changes its appearance, but it still looks not the same as a disabled single-line checkbox; in particular, on Classic Windows theme the text doesn't become sunken.
(source: keep4u.ru)
I might be missing something, but I just disable the JCheckBox and the JLabel.
Using Java 1.7 and Windows Vista.
Here's the code
package com.ggl.testing;
import java.awt.BorderLayout;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class CheckBoxTest implements Runnable {
private JCheckBox checkBox;
private JLabel multiLineLabel;
private JFrame frame;
#Override
public void run() {
frame = new JFrame("Check Box Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
JPanel checkBoxPanel = new JPanel();
checkBox = new JCheckBox();
checkBoxPanel.add(checkBox);
String s = "<html>When in the course of human events it becomes"
+ "<br>necessary for one people to dissolve the political"
+ "<br>bands which have connected them with another and to"
+ "<br>assume among the powers of the earth, the separate"
+ "<br>and equal station to which the Laws of Nature and"
+ "<br>of Nature's God entitle them, a decent respect to the"
+ "<br>opinions of mankind requires that they should declare"
+ "<br>the causes which impel them to the separation.";
multiLineLabel = new JLabel(s);
multiLineLabel.setLabelFor(checkBox);
checkBoxPanel.add(multiLineLabel);
mainPanel.add(checkBoxPanel, BorderLayout.CENTER);
JPanel toggleButtonPanel = new JPanel();
JToggleButton toggleButton = new JToggleButton("Disable Checkbox");
toggleButton.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent event) {
JToggleButton toggleButton = (JToggleButton) event.getSource();
if (toggleButton.isSelected()) {
checkBox.setEnabled(false);
multiLineLabel.setEnabled(false);
} else {
checkBox.setEnabled(true);
multiLineLabel.setEnabled(true);
}
}
});
toggleButtonPanel.add(toggleButton);
mainPanel.add(toggleButtonPanel, BorderLayout.SOUTH);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new CheckBoxTest());
}
}
I have a Swing GUI that allows a user to add JTextFields to the GUI as needed. When I run this locally on the console (on ubuntu), everything works fine.. When I run the GUI from Cygwin on a Windows box using X11 forwarding, everything starts out fine, but when I click the "add" button to put a new JTextField on the GUI, the text field shows up as expected, but I can't click in it or modify it, etc., for a long time. In fact, I can't click in the original text fields either.. After a little more than 30 seconds, the text fields come back to life and work normally until I click "add" again.
I've included a SSCCE below that demonstrates the problem. Again, this only seems to happen when running with X11-forwarding, and if I run on the Ubuntu console directly, it works as expected, so I'm not sure if this will be reproduce-able for everyone else.
One last piece of information - in my real program, clicking the add button causes a JComboBox and two JTextFields to be added. The combo box is responsive right away, but all text fields on the GUI (new ones and old ones too) are not.
HmmFrame.java:
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
public class HmmFrame extends JFrame
{
ArrayList< JTextField > fields;
JPanel mainPan;
JButton addButton;
HmmFrame()
{
super("Hmmm");
JTextField curField;
fields = new ArrayList< JTextField >();
setLayout(new FlowLayout());
mainPan = new JPanel(new FlowLayout());
this.add(mainPan);
addButton = new JButton("Add");
addButton.addActionListener(new HmmListener());
this.add(addButton);
curField = new JTextField("Try");
fields.add(curField);
updateGUI();
setVisible(true);
}
public void updateGUI()
{
mainPan.removeAll();
for (JTextField curField : fields)
{
mainPan.add(curField);
}
pack();
}
public class HmmListener implements ActionListener
{
public void actionPerformed(ActionEvent actEv)
{
JTextField curField;
curField = new JTextField("New One" + fields.size());
fields.add(curField);
updateGUI();
}
}
}
Hmm.java (driver)
public class Hmm
{
public static void main(String [] args)
{
HmmFrame hmmFrame;
hmmFrame = new HmmFrame();
}
}
I have a problem where when I try and add a mouselistener to a JLabel or JButton in a JTextPane I get the error "cannot be converted to Mouselistener by invocation conversion". I would prefer to have the component in a JEditorPane. I also heard a HyperlinkEvent could be used.
Basicly I want a component that can be right/left clicked in a JEditorPane(preffered)/JTextPane. Any help would be appreciated
Now it works (sortof) it only recives right clicks and I need to not draw button edges. Can I underline the button's text?
Example code follows...
import java.awt.*;
import javax.swing.*;
import java.awt.Color;
import javax.swing.JTextPane;
import javax.swing.JButton;
import java.applet.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class jlabeltest extends Applet {
public void init() {
jlabeltest editorPaneExample = new jlabeltest();
editorPaneExample.setSize(550, 300);
// editorPaneExample.setText("tutorialData.com");
editorPaneExample.setVisible(true);
}
public jlabeltest() {
JTextPane editorPane = new JTextPane();
editorPane.setSelectedTextColor(Color.red);
editorPane.setText("<p color='#FF0000'>Cool!</p>");
InlineB label = new InlineB("JLabel");
label.setAlignmentY(0.85f);
label.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e)
{
if (e.isPopupTrigger())
{
JOptionPane.showMessageDialog(null,"Hello!");
// do your work here
}
}
});
editorPane.insertComponent(label);
this.add(editorPane);
}
}
InlineB.java
import javax.swing.JButton;
public class InlineB extends JButton {
public InlineB( String caption ) {
super( caption );
}
}
I'm not sure what you want the question is everywhere.
But look too underline text of a JButton simply set the text of the button with HTML tags:
//added <u></u> to underlone button
InlineB label = new InlineB("<html><u>JLabel</u></html>");
as for the left click add a check to your if statement for the MouseEvent.BUTTON1 or SwingUtilities.isLeftMouseButton(MouseEvent me):
//added check for MouseEvent.BUTTON1 which is left click
if (e.isPopupTrigger() || e.getButton() == MouseEvent.BUTTON1) {
}
To not draw the borders of the JButton simply call setBorder(null); either in the InlineB class or on the InlineB instance (I did it within the class):
public InlineB(String caption) {
super(caption);
setBorder(null);//set border to nothing
}
also I see that you dont set the content type of the JTextPane, which you should:
//set content as html
editorPane.setContentType("text/html");
I did a small example though I did not use an Applet but its very easy to port:
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class Test {
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test().createAndShowUI();
}
});
}
private void createAndShowUI() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initComponents(frame);
frame.pack();
frame.setVisible(true);
}
private void initComponents(JFrame frame) {
JTextPane editorPane = new JTextPane();
editorPane.setSelectedTextColor(Color.red);
//set content as html
editorPane.setContentType("text/html");
editorPane.setText("<p color='#FF0000'>Cool!</p>");
//added <u></u> to underlone button
InlineB label = new InlineB("<html><u>JLabel</u></html>");
label.setAlignmentY(0.85f);
label.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
//added check for MouseEvent.BUTTON1 which is left click
if (e.isPopupTrigger() || e.getButton() == MouseEvent.BUTTON1) {
JOptionPane.showMessageDialog(null, "Hello!");
// do your work here
}
}
});
editorPane.insertComponent(label);
frame.getContentPane().add(editorPane);
}
}
class InlineB extends JButton {
public InlineB(String caption) {
super(caption);
setBorder(null);//set border to nothing
}
}
I have a problem where when I try and add a mouselistener to a JLabel or JButton in a JTextPane I get the error "cannot be converted to Mouselistener by invocation conversion".
The object you are passing to addMouseListener() implements the MouseListener interface. Right? (Just seen the code sample. Mouse adapter seems right).
You now say Now it works (sortof). Does it mean you have corrected that error?
BTW if that is resolved and you have subsequent problems, and they are reusable by the community, then i would advise to open a separate question: https://meta.stackexchange.com/questions/48345/what-is-the-etiquette-for-changing-the-substance-of-a-question
I would prefer to have the component in a JEditorPane.
I guess you mean the component you are listening. Anyway I'm not sure the JEditorPane is meant to be used as other components' container.
I also heard a HyperlinkEvent could be used.
HyperLinkEvent is meant for ENTERED, EXITED, and ACTIVATED event types. You are intending to handle Hyperlink events or mouse events?
Basicly I want a component that can be right/left clicked in a JEditorPane(preffered)/JTextPane. Any help would be appreciated
I would advise next time give the scope/context of the question first. I guess you mean you want something (can you be more specific?) on top of a text pane that can be clicked. Anyway I'm surprise you intend to use JEditorPane that way.
I have a very simple example. A button on the bottom of the screen that says "hi" and when its clicked it prints "hello" to the console. However, When I press the button, it doesn't change visually. Its the same with the other JSwing interactors, but for a SSCCE, here you go.
import acm.program.*;
import javax.swing.*;
import java.awt.event.*;
public class SimpleGUI extends ConsoleProgram {
public void init() {
JButton hi = new JButton("Hi");
add(hi, SOUTH);
addActionListeners();
}
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (cmd.equals("Hi")) println("Hello there sexy");
}
}
Appearance of Swing controls (including buttons) is controlled by the look-n-feel. This includes whether or not buttons look depressed when clicked.
This may help:
http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html