JRadioButton: how to replace text by IconImage? - java

I want to replace the text in my radio button list by an icon.
I've tried this:
rotateButton = new JRadioButton(rotateIcon.getImage());
But this replaces the radio button and text by the icon. I would like to keep the radio button and display the image.
What should I do?
What I'm currently getting is:
But I want it to end up with this:

Create a JRadioButton with no text and put a JLabel with the image next to it. You can also create a class to hide complexity.
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.ChangeListener;
public class RadioButtonWithImage extends JPanel {
private JRadioButton radio = new JRadioButton();
private JLabel image;
public RadioButtonWithImage(Icon icon) {
image = new JLabel(icon);
add(radio);
add(image);
}
public void addToButtonGroup(ButtonGroup group) {
group.add(radio);
}
public void addActionListener(ActionListener listener) {
radio.addActionListener(listener);
}
public void addChangeListener(ChangeListener listener) {
radio.addChangeListener(listener);
}
public Icon getImage() {
return image.getIcon();
}
public void setImage(Icon icon) {
image.setIcon(icon);
}
} // end class RadioButtonWithImage

public JRadioButton(String text, Icon icon) and simple example here

I just reproduced your described behavior using this source:
import java.awt.Image;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.net.URL;
class RadioWithImage {
public static void main(String[] args) throws Exception {
URL url = new URL("http://www.gravatar.com/avatar/" +
"a1ab0af4997654345d7a949877f8037e?s=128");
Image image = ImageIO.read(url);
final ImageIcon imageIcon = new ImageIcon(image);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JRadioButton radioButton = new JRadioButton("A.T.", imageIcon);
JOptionPane.showMessageDialog(null, radioButton);
}
});
}
}
It seems like a bug to me, though I cannot recall seeing a radio with an icon. How are they supposed to look?
Time to reach into my 'box of hacks'.
import javax.swing.*;
class RadioWithImage {
public static void main(String[] args) throws Exception {
String url = "http://www.gravatar.com/avatar/" +
"a1ab0af4997654345d7a949877f8037e?s=128";
final String html = "<html><body><img src='" +
url +
"' width=128 height=128>";
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JRadioButton radioButton = new JRadioButton(html);
JOptionPane.showMessageDialog(null, radioButton);
}
});
}
}
This technique will not work if:
The use-case requires other types of icons (pressed, roll-over, selected etc.)
The button is disabled (it will render incorrectly).

There is no radio button constructor that allows an image as the content argument instead of a text. The only way to replace the text of a radio button by an image it is generate html and pass it as an argument to the default constructor.
import javax.swing.*;
class RadioWithImage {
public static void main(String[] args) throws Exception {
URL url = Windows_ChordsGenerator.class.getResource("/images/img1.png");
final String html = "<html><body><img src='" + url.toString() +"'>";
JRadioButton radioButton = new JRadioButton(html);
}
}

Related

Customize jFileChooser vertical scrollbar

I'm using a jFileChooser and I'm trying to achieve the following :
https://i.stack.imgur.com/O6MNj.png
I'm trying to force the the LIST view to have a VERTICAL scroll bar or my second option is to disable the size and modified columns from the details view.
EDIT:
Is there any way that I can insert a JScrollBar inside the jFileChooser?
You can access the JList and change the orientation of the list as follows:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import java.util.List;
class FileChooserList
{
private static void createAndShowUI()
{
JFileChooser fileChooser = new JFileChooser(".");
// Change list orientation
JList list = SwingUtils.getDescendantsOfType(JList.class, fileChooser).get(0);
list.setLayoutOrientation( JList.VERTICAL );
fileChooser.showOpenDialog(null);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
The above code requires the Swing Utils class.
disable the size and modified columns from the details view
Depends on what you mean by "disable".
You can remove those columns from the view of the table:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import java.util.List;
class FileChooserDetails
{
private static void createAndShowUI()
{
JFileChooser fileChooser = new JFileChooser(".");
// Show the Details view of the file chooser
Action details = fileChooser.getActionMap().get("viewTypeDetails");
details.actionPerformed(null);
// Remove columns from view
JTable table = SwingUtils.getDescendantsOfType(JTable.class, fileChooser).get(0);
TableColumnModel tcm = table.getColumnModel();
tcm.removeColumn( tcm.getColumn(3) );
tcm.removeColumn( tcm.getColumn(1) );
fileChooser.showOpenDialog(null);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}

Make text in JButton not visible

I made a button and did a .setText() on it because I have to compare the value of the .setText() with something else.
I applied the .setText() to a JButton, but I don't want the text to be visible in my button.
If I do setVisible(false) then it hides the whole button, but I only want it to hide the text.
Is there an option for this? I've considered making a custom font and apply it on the text in the .setText() but I'm wondering if there's a more efficient option to my problem.
Thanks in advance guys.
EDIT: I can't use .setText(" ") because I have to compare the value within it.
You state:
EDIT: I can't use .setText(" ") because I have to compare the value within it.
Nonsense. As I've mentioned in a comment, set the JButton's text to " ", and don't use the JButton's text for comparison. Instead use its actionCommand easily obtained via getActionCommand(). Or use a HashMap<JButton, SomethingElse>.
You may consider changing the JButton's Action when you need to change its behavior and state which is easily done by calling setAction(...)
For example,
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ButtonActions {
private static void createAndShowGui() {
JPanel mainPanel = new JPanel();
JButton myButton = new JButton();
StartAction startAction = new StartAction();
PauseAction pauseAction = new PauseAction();
BlankAction blankAction = new BlankAction();
startAction.setNextAction(pauseAction);
pauseAction.setNextAction(blankAction);
blankAction.setNextAction(startAction);
myButton.setAction(startAction);
mainPanel.add(myButton);
JFrame frame = new JFrame("ButtonActions");
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();
}
});
}
}
class SwappingAction extends AbstractAction {
private Action nextAction;
public SwappingAction(String text) {
super(text);
}
public void setNextAction(Action nextAction) {
this.nextAction = nextAction;
}
public Action getNextAction() {
return nextAction;
}
#Override
/**
* super method needs to be called in child for swap to work
*/
public void actionPerformed(ActionEvent e) {
System.out.println("ActionCommand: " + e.getActionCommand());
((AbstractButton)e.getSource()).setAction(nextAction);
}
}
class StartAction extends SwappingAction {
public static final String START = "Start";
public StartAction() {
super(START);
}
#Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
// start-specific code goes here
}
}
class PauseAction extends SwappingAction {
public static final String PAUSE = "Pause";
public PauseAction() {
super(PAUSE);
}
#Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
// pause-specific code goes here
}
}
class BlankAction extends SwappingAction {
public static final String BLANK = " ";
public BlankAction() {
super(BLANK);
}
#Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
}
}
Write buttonName.setText(" ") this will not display any name to the button. And whenever you feel like displaying the name (on any event) then set it again buttonName.setText("some text")
If you insist not to use setText(""), try setting same colour as a background colour and text colour. Check the below links
setBackground(java.awt.Color)
setForeground(java.awt.Color)
Why don't you name the first button " " (1 space).
the second: " " (2 spaces)
the third: " "(3 spaces) and so on ..
Now, compare:
if((event.getActionCommand()).equals(" "))
{ //1st button }
if((event.getActionCommand()).equals(" "))
{ //2nd button }
..and so on
where event is an object of ActionEvent
This way the buttons will have a unique names and be invisible.
Horrible coding, I know. But it does the trick ;)
Instead of .setText(), use .setTag() and .getTag() to attach some value to a View - including a Button - for later retrieval.
These methods are there directly for that kind of purpose.

Java Applet Text highlights on rollover

I'm trying to figure out how to make non-editable text (not a JTextField) whose background color changes when the mouse rolls over it. I tried using JButton implementing ActionListener and hiding elements to make the button appear to be just text, but it only allows me to change icons on rollover and detect when the button is clicked. Another thought was to use MouseListener and declare the specific coordinates of a rectangle around the text, where upon mouseMoved it could initiate the highlight. But w/ that there's a problem for varying string lengths and word wrap etc. What is the best object, and listener combo to achieve the effect of a highlighted text field on mouse rollover?
Hmm maybe use a foucs listener and when the field gains foucs select all the text?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TextField extends JTextField {
public TextField(String text) {
super(text);
addFocusListener(new FocusAdapter() {
#Override
public void focusGained(FocusEvent fe) {
selectAll();
}
});
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextField tf = new JTextField("normal field");
f.add(tf, BorderLayout.CENTER);
TextField ftf =
new TextField("funny text field");
f.add(ftf, BorderLayout.SOUTH);
f.pack();
f.setVisible(true);
}
});
}
}
EDIT:
Hmmm actually found an even better way with the above method you'd have to click on the textfield to gain focus, now i've used a thread to check when the mouse is over the components co-ordinates and then to highlight the field, I used a boolean to control the highlighting as constant highlighting throws an error. Hope this is what you want:
import java.awt.*;
import javax.swing.*;
public class TextFieldHighlight extends JTextField {
static JTextField ftf;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ftf = new JTextField("Highlight");
ftf.setEditable(false);
f.add(ftf, BorderLayout.CENTER);
f.pack();
f.setVisible(true);
Thread thread = new Thread(new Runnable() {
boolean focused = false;
#Override
public void run() {
while (true) {
if (mouseIsOverDisplayPanel()) {
if (ftf.hasFocus() && focused == false) {
ftf.selectAll();
focused = true;
} else if (!ftf.hasFocus()) {
focused = false;
}
}
}
}
});
thread.start();
}
});
}
private static boolean mouseIsOverDisplayPanel() {
if (MouseInfo.getPointerInfo().getLocation().x >= ftf.getLocationOnScreen().x
&& MouseInfo.getPointerInfo().getLocation().x <= ftf.getLocationOnScreen().x + ftf.getWidth()
&& MouseInfo.getPointerInfo().getLocation().y >= ftf.getLocationOnScreen().y
&& MouseInfo.getPointerInfo().getLocation().y <= ftf.getLocationOnScreen().y + ftf.getHeight()) {
return true;
} else {
return false;
}
}
}

Communication between JOptionPane buttons and a custom panel

I have made a multiple input dialog by building a JPanel with the fields I want and adding it to a JOption pane
JMainPanel mainPanel = new JMainPanel(mensaje, parametros, mgr);
int i = JOptionPane.showOptionDialog(null, mainPanel, "Sirena",
JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null,
new String[] {"Aceptar", "Cancelar"}, "Aceptar");
However I'm having trouble with the buttons, because some of the fields are required. How can I make the "Ok" button to be enabled once every required field is up, or making the click on the button to make the validations and do not close the pane until every required field is filled?
From the Java API, I found this:
options - an array of objects indicating the possible choices the user
can make; if the objects are components, they are rendered properly;
non-String objects are rendered using their toString methods; if this
parameter is null, the options are determined by the Look and Feel
So, can't I pass custom buttons as parameter?
Looks like I will have to make my own JDialog? for which case, I don't know how to make it return an int just like JOptionPane does, any recommended tutorial?
In the example options is {"Aceptar", "Cancelar"} which are the displayed buttons,
PS. I have full controll over the fields I added to the JPanel.
This is a screenshot of the JOptionPane:
I don't think that you can de-activate a JOptionPane's selections buttons, but one way to still use the JOptionPane is to simply re-display it if the required fields have not been set. You could display an error message JOptionPane first describing the error, and then display a new JOptionPane that holds the same JPanel as its second parameter -- so that the data already entered has not been lost. Otherwise, you may want to create your own JDialog which by the way isn't that hard to do.
Edit
I'm wrong. You can enable and disable the dialog buttons if you use a little recursion.
For example:
import java.awt.Component;
import java.awt.Container;
import java.awt.event.*;
import java.util.HashSet;
import java.util.Set;
import javax.swing.*;
public class Foo extends JPanel {
private static final String[] DIALOG_BUTTON_TITLES = new String[] { "Aceptar", "Cancelar" };
private JCheckBox checkBox = new JCheckBox("Buttons Enabled", true);
private Set<AbstractButton> exemptButtons = new HashSet<AbstractButton>();
public Foo() {
JButton exemptBtn = new JButton("Exempt Button");
JButton nonExemptBtn = new JButton("Non-Exempt Button");
add(checkBox);
add(exemptBtn);
add(nonExemptBtn);
exemptButtons.add(checkBox);
exemptButtons.add(exemptBtn);
checkBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
allBtnsSetEnabled(checkBox.isSelected());
}
});
}
private void allBtnsSetEnabled(boolean enabled) {
JRootPane rootPane = SwingUtilities.getRootPane(checkBox);
if (rootPane != null) {
Container container = rootPane.getContentPane();
recursiveBtnEnable(enabled, container);
}
}
private void recursiveBtnEnable(boolean enabled, Container container) {
Component[] components = container.getComponents();
for (Component component : components) {
if (component instanceof AbstractButton && !exemptButtons.contains(component)) {
((AbstractButton) component).setEnabled(enabled);
} else if (component instanceof Container) {
recursiveBtnEnable(enabled, (Container) component);
}
}
}
public int showDialog() {
return JOptionPane.showOptionDialog(null, this, "Sirena",
JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null,
DIALOG_BUTTON_TITLES, "Aceptar");
}
private static void createAndShowGui() {
Foo foo = new Foo();
int result = foo.showDialog();
System.out.println(DIALOG_BUTTON_TITLES[result]);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
This code uses listeners to check the state of a JCheckBox, but you can have listeners (DocumentListeners) listening to text field documents if you desire to know if they have data or not. The code then gets the JRootPane that holds the JCheckBox, then the root pane's contentPane, and all components of the dialog are held by this. It then recurses through all the components held by the dialog. If a component is a Container, it recurses through that container. If the component is an AbstractButton (such any JButton or checkbox), it enables or disables -- except for buttons held in the exempt buttons set.
A better example with document listeners
import java.awt.*;
import java.awt.event.*;
import java.util.HashSet;
import java.util.Set;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class Foo2 extends JPanel {
private static final String[] DIALOG_BUTTON_TITLES = new String[] {
"Aceptar", "Cancelar" };
private static final int FIELD_COUNT = 10;
private Set<AbstractButton> exemptButtons = new HashSet<AbstractButton>();
private JTextField[] fields = new JTextField[FIELD_COUNT];
public Foo2() {
setLayout(new GridLayout(0, 5, 5, 5));
DocumentListener myDocListener = new MyDocumentListener();
for (int i = 0; i < fields.length; i++) {
fields[i] = new JTextField(10);
add(fields[i]);
fields[i].getDocument().addDocumentListener(myDocListener);
}
// cheating here
int timerDelay = 200;
Timer timer = new Timer(timerDelay , new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
checkDocsForText();
}
});
timer.setRepeats(false);
timer.setInitialDelay(timerDelay);
timer.start();
}
private void checkDocsForText() {
for (JTextField field : fields) {
if (field.getText().trim().isEmpty()) {
allBtnsSetEnabled(false);
return;
}
}
allBtnsSetEnabled(true);
}
private void allBtnsSetEnabled(boolean enabled) {
JRootPane rootPane = SwingUtilities.getRootPane(this);
if (rootPane != null) {
Container container = rootPane.getContentPane();
recursiveBtnEnable(enabled, container);
}
}
private void recursiveBtnEnable(boolean enabled, Container container) {
Component[] components = container.getComponents();
for (Component component : components) {
if (component instanceof AbstractButton && !exemptButtons.contains(component)) {
((AbstractButton) component).setEnabled(enabled);
} else if (component instanceof Container) {
recursiveBtnEnable(enabled, (Container) component);
}
}
}
public int showDialog() {
return JOptionPane.showOptionDialog(null, this, "Sirena",
JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null,
DIALOG_BUTTON_TITLES, "Aceptar");
}
private class MyDocumentListener implements DocumentListener {
public void removeUpdate(DocumentEvent arg0) {
checkDocsForText();
}
public void insertUpdate(DocumentEvent arg0) {
checkDocsForText();
}
public void changedUpdate(DocumentEvent arg0) {
checkDocsForText();
}
}
private static void createAndShowGui() {
Foo2 foo = new Foo2();
int result = foo.showDialog();
if (result >= 0) {
System.out.println(DIALOG_BUTTON_TITLES[result]);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I suggest you to define some properties into your JPanel extended class, and use PropertyChangeListener to listen the occured changes and enable/disable relative buttons.
Here's an article.
Another issue maybe finding the ok/cancel buttons in the hierarchy of components, since the JDialog is created through JOptionPane and you haven't a reference to the buttons. Here's a useful thread .
You can add a property to a JComponent using putClientProperty method.
When changes occurs to a given property a PropertyChanged event is raised.
So in your example you can define a boolean property indicating that required that are inserted into the JDialog. Then add a PropertyChangeListener that when is notified enable/disable the ok button.

Blackberry application showing blank screen

Hi everyone im having problems in my Blackberry application.................
I have made a simple application it starts with a file called AppStarter
package in.EventTimer;
import net.rim.device.api.ui.UiApplication;
public class AppStarter extends UiApplication
{
public static void main (String[] args)
{
AppStarter theApp = new AppStarter ();
theApp.enterEventDispatcher ();
}
public AppStarter()
{
//display a new screen
pushScreen (new ConnectionSettings ());
}
}
From this AppStarter file it pushes to the second file which is a Screen for the ConnectionSettings
package in.EventTimer;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.MainScreen;
public class ConnectionSettings extends MainScreen
{
public void RadioButton()
{
RadioButtonGroup rbg = new RadioButtonGroup();
RadioButtonField rb1 = new RadioButtonField("tcp");
RadioButtonField rb2 = new RadioButtonField("gprs");
RadioButtonField rb3 = new RadioButtonField("wifi");
rbg.add(rb1);
rbg.add(rb2);
rbg.add(rb3);
}
public boolean onClose()
{
Dialog.alert ("Exit Connection Settings!");
System.exit (0);
return true;
}
}
But when iam running this application in my Blackberry 9700 simulator it is just giving the blank white screen and when im exiting that white screen it is giving the message exitconnection settings which means it is on the connection settings screen but when i run it is showing blank white screen........i have tried many things but no solution yet ............so plz help or suggest something.
Thanks in advance
Try adding the following method to the ConnectionSettings class:
public ConnectionSettings()
{
super();
LabelField title = new LabelField("HelloWorld Sample",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
setTitle(title);
add(new RichTextField("Hello World!"));
}
Looks like you are missing a constructor... For your MainScreen class
So the final code should look like this:
package in.EventTimer;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.MainScreen;
public class ConnectionSettings extends MainScreen {
public void RadioButton()
{
RadioButtonGroup rbg = new RadioButtonGroup();
RadioButtonField rb1 = new RadioButtonField("tcp");
RadioButtonField rb2 = new RadioButtonField("gprs");
RadioButtonField rb3 = new RadioButtonField("wifi");
rbg.add(rb1);
rbg.add(rb2);
rbg.add(rb3);
add(rb1); //Added by eSniff
add(rb2); //Added by eSniff
add(rb3); //Added by eSniff
}
//Begin added by eSniff
public ConnectionSettings()
{
super();
LabelField title = new LabelField("APP STARTER",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
setTitle(title);
add(new RichTextField("Hello World!"));
RadioButton();
}
//End added by eSniff
public boolean onClose()
{
Dialog.alert ("Exit Connection Settings!");
System.exit (0);
return true;
}
}
Make the variable "rgb" into a class field
Define a constructor.
In that constructor, you must first call the function RadioButtons(), then call add(rgb) in your constructor, you must first call RadioButtons(), then invoke add(rgb) to ensure that your fields show up on screen.

Categories

Resources