I have a JPanel that currently has a swing.box in it, which in itself houses an arbitrary number of JButtons.
Now one of the JButtons has the ability to create a new JButton, which goes fine.
However, after creating said new button, I want the button to go in the list at the right position (alphabetically sorted) which also goes fine. I am however sure that it is never the last button as I add some standard buttons at the end.
Now the problem is that I cannot nuke the box that has said buttons in them after which I rebuild the box.
(also see https://github.com/Diamundo/PhotoSelectorSys/ButtonPanel.java and specifically at line 42, start of function initButtons() )
(problem I also have, is that I add buttons with a preferred size which does take effect if I put them straight in the panel, but not if I put them in the box... so if you have a solution which lets me delete all buttons instead of the box that's also very welcome :D )
package photoselectorsys;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.util.ArrayList;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class ButtonPanel extends JPanel {
private AppFrame listener;
private String path;
private Box box;
public ButtonPanel(int width, int height){
setPreferredSize(new Dimension(width, height));
setVisible(true);
box = Box.createVerticalBox();
}
public void setPath(String path){
this.path = path;
initButtons();
// pushButtons();
this.revalidate();
}
/*public void pushButtons() {
for(JButton jb : buttons) { //buttons was an ArrayList of button names. Is now the box.
this.remove(jb); //remove the button from the panel.
}
for(JButton jb : buttons) { //buttons should be changed to the box
add(jb);
}
}*/
public void initButtons(){
/* if(box.hasButtons()) {
box.nuke();
box = new Box(..);
}
*/
JButton jb;
File directory = new File(path);
File[] listFiles = directory.listFiles();
ArrayList<String> btns = new ArrayList<>();
for (File file : listFiles) {
if (file.isDirectory()) {
btns.add(file.getName());
}
}
btns.add("Add a new Button");
btns.add("Rotate CW");
btns.add("Rotate CCW");
btns.add("Rotate 180*");
System.out.println("buttons " + btns.size());
if(btns.size() > 4) { //if there's at least one folder, size > 4. Else add one big button or ask to create subfolder
for(String btn : btns) {
jb = new JButton(btn);
jb.setFont(new Font("Arial", Font.PLAIN, 20));
jb.setPreferredSize(new Dimension(this.getWidth()-20, 40));
jb.setVisible(true);
jb.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent arg0) {
onButtonPress((JButton) arg0.getSource());
}
#Override
public void mouseEntered(MouseEvent e) { /* unused */ }
#Override
public void mouseExited(MouseEvent e) { /* unused */ }
#Override
public void mousePressed(MouseEvent e) { /* unused */ }
#Override
public void mouseReleased(MouseEvent e) { /* unused */ }
});
/*box.*/add(jb);
}
} else {
// do add folder magic from the start.
jb = new JButton("Add a new Button");
jb.setFont(new Font("Arial", Font.PLAIN, 20));
jb.setPreferredSize(new Dimension(this.getWidth()-20, this.getHeight()-30));
jb.setSize(new Dimension(this.getWidth()-20, this.getHeight()));
jb.setVisible(true);
jb.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent arg0) {
onButtonPress((JButton) arg0.getSource());
}
#Override
public void mouseEntered(MouseEvent e) { /* unused */ }
#Override
public void mouseExited(MouseEvent e) { /* unused */ }
#Override
public void mousePressed(MouseEvent e) { /* unused */ }
#Override
public void mouseReleased(MouseEvent e) { /* unused */ }
});
/*box.*/add(jb);
}
// add(box);
}
public void onButtonPress(JButton jb){
// not interesting for this question. See github for function.
}
public void addListener(AppFrame listener) {
this.listener = listener;
}
}
To change the buttons in your box you don't have to create a new box but rather do one of the following 2 things:
a) add the button at the correct position using box.add( button, index )
b) remove all buttons using box.removeAll() and (re)add the buttons as needed
I'd prefer variant a) but there might be cases where rebuilding the box contents from scratch might be the better way.
Normally that alone should be sufficient since the component should realize it's layout is invalid and needs to be recalculated. If this doesn't happen or you need to revalidate the parent container as well for some reason call the invalidate() method on the relevant component.
Related
I have a table. If I right-click I got a JPopUpMenu but before the pop-up I want to select the row where the right-click event is done. Here is what I've tried.
path_tbl.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
System.out.println(e.getPoint());
Point point = e.getPoint();
int selectedRow = path_tbl.rowAtPoint(point);
path_tbl.setRowSelectionInterval(selectedRow, selectedRow);
}
});
In that event, I cannot get any output from the console when I right-click. However, when I left-click, points are printed to the console.
java.awt.Point[x=105,y=76]
So, this event only works when I left-click. How can I make this event work with right-click?
Since you want custom mouse behavior, you should not use setComponentPopupMenu.
Instead, display the JPopupMenu yourself, using JPopupMenu’s show method:
JPopupMenu menu = /* ... */;
path_tbl.addMouseListener(new MouseAdapter() {
private void showPopupMenuFor(MouseEvent e) {
if (menu.isPopupTrigger(e)) {
Point point = e.getPoint();
int row = path_tbl.rowAtPoint(point);
if (!path_tbl.isRowSelected(row)) {
path_tbl.setRowSelectionInterval(row, row);
}
menu.show(path_tbl, e.getX(), e.getY());
}
}
#Override
public void mousePressed(MouseEvent e) {
showPopupMenuFor(e);
}
#Override
public void mouseReleased(MouseEvent e) {
showPopupMenuFor(e);
}
#Override
public void mouseClicked(MouseEvent e) {
showPopupMenuFor(e);
}
});
You must check the MouseEvent in both mousePressed and mouseReleased, because exactly when a context menu is triggered depends on the platform and the look-and-feel. (Checking in mouseClicked may or may not be necessary, but it doesn’t hurt.)
In most cases, I'm lazy, so if I don't need to do something, then I'd prefer not to. In this case, I'd prefer to make use of the existing API works as much as possible, meaning, make use of JComponent#setComponentPopupMenu, as it will take care of the "how" and "when" the popup should be shown, based on the current platform.
However, as you have discovered, by default, JTable will NOT select the row when the user presses the "right" mouse button, for that, you could just continue with your current workflow, but, checking to see if the MouseEvent is actually a "right" click.
Lucky for us, some of the original Swing developers were also "lazy" and they provided us with SwingUtilities.isRightMouseButton, yea 🎉
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
public final class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
DefaultTableModel model = new DefaultTableModel(0, 10);
for (int row = 0; row < 10; row++) {
Vector data = new Vector(10);
for (int col = 0; col < 10; col++) {
String value = row + "x" + ((char) (col + 'A'));
data.add(value);
}
model.addRow(data);
}
JPopupMenu menu = new JPopupMenu();
menu.add("Hello");
menu.add("This looks interesting");
menu.add("I like bi-planes");
JTable table = new JTable(model);
table.setComponentPopupMenu(menu);
table.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
Point point = e.getPoint();
int row = table.rowAtPoint(point);
if (!table.isRowSelected(row)) {
table.setRowSelectionInterval(row, row);
}
}
}
});
add(new JScrollPane(table));
}
}
}
I have a JComboBox that takes up too much room my GUI because of the long Strings it contains. I only need to see their full length while making a selection. So, I'd like the JComboBox to be full size only then and shorter otherwise.
The following code seems to work. But, since I'm very much a Java newbie, I'm just wondering if there's a better or more standard way of doing this.
Thanks.
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
public class DynamicJComboBox{
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.setSize(250, 100);
JComboBox box = new JComboBox();
box.addItem("Really Long Line Number One");
box.addItem("Really Long Line Number Two");
box.addItem("Really Long Line Number Three");
box.addItem("Really Long Line Number Four");
box.setPreferredSize(new Dimension(100, 30));
box.addPopupMenuListener (new PopupMenuListener() {
#Override
public void popupMenuCanceled(PopupMenuEvent e) {}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
box.setSize(100,30);
}
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
box.setSize(200,30);
}
});
frame.add(box);
frame.setVisible(true);
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception exc) {}
SwingUtilities.invokeLater(() -> {
createAndShowGUI();
});
}
}
The following code seems to work
Not really because you change the size of the combo box which would cause the combo box to overwrite any component display on the right of it. Also, the combo box arrow is drawn in the middle of the combo box.
Check out Combo Box Popup. This solution also uses a PopupMenuListener (so you were on the right track) but it only increases the width of the popup when it is displayed, not the combo box as well.
Small hack to get pop up menu size bigger enough to show items even though the combo box size could be smaller
Source: http://www.jroller.com/santhosh/entry/make_jcombobox_popup_wide_enough
import java.awt.Dimension;
import java.util.Vector;
import javax.swing.ComboBoxModel;
import javax.swing.JComboBox;
public class ComboBoxFullMenu<E> extends JComboBox<E> {
public ComboBoxFullMenu(E[] items) {
super(items);
addActionListener(this);
}
public ComboBoxFullMenu(Vector<E> items) {
super(items);
addActionListener(this);
}
public ComboBoxFullMenu(ComboBoxModel<E> aModel) {
super(aModel);
addActionListener(this);
}
/**
* Small hack to get pop up menu size bigger enough to show items even though
* the combo box size could be smaller
* */
private boolean layingOut = false;
#Override
public void doLayout(){
try{
layingOut = true;
super.doLayout();
}finally{
layingOut = false;
}
}
#Override
public Dimension getSize(){
Dimension dim = super.getSize();
if ( !layingOut ) {
dim.width = Math.max(dim.width, getPreferredSize().width);
}
return dim;
}
}
So I have a swing application where a button opens up a window. It is pretty simple, to open it I use:
private static logPicker logWindow;
static boolean logViewerOpen = false;
if (!logViewerOpen) {
logWindow = new logPicker();
logWindow.frmOpenLog.setVisible(true);
logViewerOpen = true;
}
else {
logWindow.frmOpenLog.requestFocus();
}
I also have a window listener to know when the viewer is closed:
frmOpenLog.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent arg0) {
indexPage.logViewerOpen = false;
frmOpenLog.dispose();
}
});
I do this because I want to keep track on whether or not the window is already open, because if it is then I have to update information. The window I open has a list of logs that a user can double click on to view the information about that log. The problem right now is, when a user double clicks on the list it gets called however many times I have opened and closed that window. example: I open the log picker window, and then close it. I open it again and double click on the log I want to view, and it will open 2 of those. I have the double click simple do a .doClick() on the Open Log button. The weird thing is, when I use the button to open the log, it does not do this. It will only open the log once. Here is the code for the double click event and the Open Log button.
#Override
public void mouseClicked(MouseEvent arg0) {
if (arg0.getClickCount() == 2) {
btnOpenLog.doClick();
}
}
btnOpenLog.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
logViewer window = new logViewer(log.getSelectedValue());
window.frmLogViewer.setVisible(true);
}
});
#LiverpoolFTW: Please provide a SSCCE demonstrating the problem. Absent sufficient code, I speculate you're (re-)adding the MouseListener/MouseAdapter each time your window is opened. The following example works as desired as-is, incrementing the clickCount once per button press or label double-click. But if you uncomment the indicated section, you'll see that the doClick() is executed twice when you double-click the label. If you have, for example, some component to which you're adding a listener each time the window opens, each of those listeners will be executed.
package example.stackoverflow;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class ClickCheck extends JFrame
{
private static final long serialVersionUID = -6446528001976145548L;
private static final JButton btnOpenLog = new JButton("Open Log");
public ClickCheck()
{
JLabel label = new JLabel("Double-Click Me");
label.addMouseListener(new MouseAdapter()
{
#Override
public void mouseClicked(MouseEvent arg0) {
if (arg0.getClickCount() == 2) {
btnOpenLog.doClick();
}
}
});
// Uncomment to demonstrate the effect of multiple listeners
// label.addMouseListener(new MouseAdapter()
// {
// #Override
// public void mouseClicked(MouseEvent arg0) {
// if (arg0.getClickCount() == 2) {
// btnOpenLog.doClick();
// }
// }
// });
btnOpenLog.addActionListener(new ActionListener() {
private int clickCount = 0;
public void actionPerformed(ActionEvent e) {
System.out.println(++clickCount + ": Button clicked");
}
});
setSize(200, 200);
setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
add(btnOpenLog);
add(label);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
ClickCheck c = new ClickCheck();
c.setVisible(true);
}
});
}
}
I'm blocked with a probelm about Java and the use of JTree:
I want to create a JTree with, node by node, some JButtons components (or Images, I don't mind), like in the following picture. It will be 3 or 4 buttons in the same row. I succeed to do that.
But where I'm blocked is when I want to add a mouselistener on each of this button to manage their tooltip or an action on them.
In fact the JTree component is most of the time used to manage the action on the full node, but not on its inside components.
I did a short code, in comparaison at the real big code I have to work in, to quickly test what I say:
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.event.*;
import java.awt.*;
import java.io.IOException;
import java.net.URL;
public class TreeWithPopup extends JPanel {
DefaultMutableTreeNode root, node1, node2, node3;
public TreeWithPopup() {
MyJTree tree;
root = new DefaultMutableTreeNode("root", true);
node1 = new DefaultMutableTreeNode("node 1", true);
node2 = new DefaultMutableTreeNode("node 2", true);
node3 = new DefaultMutableTreeNode("node 3", true);
root.add(node1);
node1.add(node2);
root.add(node3);
setLayout(new BorderLayout());
tree = new MyJTree(root);
tree.setCellRenderer(new PCellRenderer());
add(new JScrollPane((JTree) tree), "Center");
}
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
public static void main(String s[]) {
JFrame frame = new JFrame("Tree with button");
TreeWithPopup panel = new TreeWithPopup();
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setForeground(Color.black);
frame.setBackground(Color.lightGray);
frame.getContentPane().add(panel, "Center");
frame.setSize(panel.getPreferredSize());
frame.setVisible(true);
frame.addWindowListener(new WindowCloser());
}
}
class WindowCloser extends WindowAdapter {
public void windowClosing(WindowEvent e) {
Window win = e.getWindow();
win.setVisible(false);
System.exit(0);
}
}
class MyJTree extends JTree implements ActionListener {
MyJTree(DefaultMutableTreeNode dmtn) {
super(dmtn);
addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent arg0) {
System.out.println("JTree.MouseListener");
}
public void mouseEntered(MouseEvent arg0) {
System.out.println("JTree.MouseListener");
}
public void mouseExited(MouseEvent arg0) {
System.out.println("JTree.MouseListener");
}
public void mousePressed(MouseEvent arg0) {
System.out.println("JTree.MouseListener");
}
public void mouseReleased(MouseEvent arg0) {
System.out.println("JTree.MouseListener");
}
});
}
public void actionPerformed(ActionEvent ae) {
System.out.println("MyJTree.ActionPerformed");
}
}
class PCellRenderer extends DefaultTreeCellRenderer {
public Component getTreeCellRendererComponent(JTree ptree, Object pvalue, boolean psel, boolean pexpanded, boolean pleaf, int prow,
boolean phasFocus) {
Box myPanel = new Box(BoxLayout.X_AXIS);
JButton myButton = new JButton("test");
Image imgToUse = null;
Image imgRollOver = null;
try {
URL urlIcon = new URL("file:///C:/1.jpg"); // <===== change their the path to icons
imgToUse = ImageIO.read(urlIcon);
urlIcon = new URL("file:///C:/2.jpg"); // <===== change their the path to icons
imgRollOver = ImageIO.read(urlIcon);
} catch (IOException e) {
e.printStackTrace();
}
myButton.setRolloverIcon(new ImageIcon(imgRollOver));
myButton.setIcon(new ImageIcon(imgToUse));
myButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
System.out.println(" detected on ");
}
});
myButton.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent arg0) {
System.out.println("myButton.MouseListener");
}
public void mouseEntered(MouseEvent arg0) {
System.out.println("myButton.MouseListener");
}
public void mouseExited(MouseEvent arg0) {
System.out.println("myButton.MouseListener");
}
public void mousePressed(MouseEvent arg0) {
System.out.println("myButton.MouseListener");
}
public void mouseReleased(MouseEvent arg0) {
System.out.println("myButton.MouseListener");
}
});
myPanel.add(myButton);
return myPanel;
}
}
You just have to change the icon path or put the two following icons at "c:/"
I also searched to use the x/y position of the row event but I was unable to find the position of my button after rendering.
If anyone can have an idea how to do that, he could be very helpful.
Thanks, at least for read this question ;-)
Tooltip support is actually provided by the TableCellRenderer directly. Your TableCellRenderer is a little muddled. It extends from DefaultTreeCellRenderer but makes no use of any of it's features, instead creating a new Box, JButton and loading icons each time a cell is rendered...
This is going to increase your memory usage a slow you application down...
Instead, try something like...
class PCellRenderer extends Box implements TreeCellRenderer {
private Image imgToUse = null;
private Image imgRollOver = null;
public PCellRenderer() {
super(BoxLayout.X_AXIS);
JButton myButton = new JButton("test");
try {
URL urlIcon = new URL("file:///C:/1.jpg"); // <===== change their the path to icons
imgToUse = ImageIO.read(urlIcon);
urlIcon = new URL("file:///C:/2.jpg"); // <===== change their the path to icons
imgRollOver = ImageIO.read(urlIcon);
} catch (IOException e) {
e.printStackTrace();
}
myButton.setRolloverIcon(new ImageIcon(imgRollOver));
myButton.setIcon(new ImageIcon(imgToUse));
add(myButton);
}
public Component getTreeCellRendererComponent(JTree ptree, Object pvalue, boolean psel, boolean pexpanded, boolean pleaf, int prow,
boolean phasFocus) {
// set the tooltip text here...
// Maybe change the icon...
return this;
}
}
Now, actually doing something...
Renderers are rubber stamps. That are not actually life components. Think of them like photos. You can take a snap shot of your friends, but you can't interact with them...same thing here...
Your idea of a MouseListener on the JTree is a correct one, in fact the JavaDocs actually have a demonstration of this...
public void mousePressed(MouseEvent e) {
int selRow = tree.getRowForLocation(e.getX(), e.getY());
TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
if(selRow != -1) {
if(e.getClickCount() == 1) {
mySingleClick(selRow, selPath);
}
else if(e.getClickCount() == 2) {
myDoubleClick(selRow, selPath);
}
}
}
I want to make it so that if I click on the JLabel, the label becomes a new label with another image attached to it.
So far my code looks like:
public class Picture extends JFrame {
private ImageIcon _image1;
private ImageIcon _image2;
private JLabel _mainLabel;
private JLabel _mainLabel2;
public Picture(){
_image1 = new ImageIcon("src/classes/picture1.jpg");
_image2 = new ImageIcon("src/classes/picture2.jpg");
_mainLabel = new JLabel(_image1);
_mainLabel2 = new JLabel(_image2);
add(_mainLabel);
pack();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Add mouseListener to your JLable and in mouseClicked(mouseEvent) method change icon of JLabel.
A sample code may be:
jLabel.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
jLabel.setIcon(newIcon);
}
});
Try using a JToggleButton instead. No need for a MouseListener, and responds to keyboard input.
import javax.swing.*;
import javax.imageio.ImageIO;
import java.net.URL;
import java.awt.Image;
class ToggleImage {
public static void main(String[] args) throws Exception {
URL url1 = new URL("http://pscode.org/media/stromlo1.jpg");
URL url2 = new URL("http://pscode.org/media/stromlo2.jpg");
final Image image1 = ImageIO.read(url1);
final Image image2 = ImageIO.read(url2);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JToggleButton button = new JToggleButton();
button.setIcon(new ImageIcon(image1));
button.setSelectedIcon(new ImageIcon(image2));
button.setBorderPainted(false);
button.setContentAreaFilled(false);
JOptionPane.showMessageDialog(null, button);
}
});
}
}
Old Code - before I realized this was about images
I want to make it so that if I click on the JLabel
What about for people who are 'mouse challenged? Use a JTextField instead. Tab to any link and hit Enter to activate.
import java.awt.Desktop;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.JTextField;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.border.MatteBorder;
import javax.swing.border.Border;
import java.net.URI;
import java.io.File;
/**
A Java 1.6+ LinkLabel that uses the Desktop class for opening
the document of interest.
The Desktop.browse(URI) method can be invoked from applications,
applets and apps. launched using Java Webstart. In the latter
two cases, the usual fall-back methods are used for sandboxed apps
(see the JavaDocs for further details).
While called a 'label', this class actually extends JTextField,
to easily allow the component to become focusable using keyboard
navigation.
To successfully browse to a URI for a local File, the file name
must be constructed using a canonical path.
#author Andrew Thompson
#version 2008/08/23
*/
public class LinkLabel
// we extend a JTextField, to get a focusable component
extends JTextField
implements MouseListener, FocusListener, ActionListener {
/** The target or href of this link. */
private URI target;
public Color standardColor = new Color(0,0,255);
public Color hoverColor = new Color(255,0,0);
public Color activeColor = new Color(128,0,128);
public Color transparent = new Color(0,0,0,0);
public boolean underlineVisible = true;
private Border activeBorder;
private Border hoverBorder;
private Border standardBorder;
/** Construct a LinkLabel that points to the given target.
The URI will be used as the link text.*/
public LinkLabel(URI target) {
this( target, target.toString() );
}
/** Construct a LinkLabel that points to the given target,
and displays the text to the user. */
public LinkLabel(URI target, String text) {
super(text);
this.target = target;
}
/* Set the active color for this link (default is purple). */
public void setActiveColor(Color active) {
activeColor = active;
}
/* Set the hover/focused color for this link (default is red). */
public void setHoverColor(Color hover) {
hoverColor = hover;
}
/* Set the standard (non-focused, non-active) color for this
link (default is blue). */
public void setStandardColor(Color standard) {
standardColor = standard;
}
/** Determines whether the */
public void setUnderlineVisible(boolean underlineVisible) {
this.underlineVisible = underlineVisible;
}
/* Add the listeners, configure the field to look and act
like a link. */
public void init() {
this.addMouseListener(this);
this.addFocusListener(this);
this.addActionListener(this);
setToolTipText(target.toString());
if (underlineVisible) {
activeBorder = new MatteBorder(0,0,1,0,activeColor);
hoverBorder = new MatteBorder(0,0,1,0,hoverColor);
standardBorder = new MatteBorder(0,0,1,0,transparent);
} else {
activeBorder = new MatteBorder(0,0,0,0,activeColor);
hoverBorder = new MatteBorder(0,0,0,0,hoverColor);
standardBorder = new MatteBorder(0,0,0,0,transparent);
}
// make it appear like a label/link
setEditable(false);
setForeground(standardColor);
setBorder(standardBorder);
setCursor( new Cursor(Cursor.HAND_CURSOR) );
}
/** Browse to the target URI using the Desktop.browse(URI)
method. For visual indication, change to the active color
at method start, and return to the standard color once complete.
This is usually so fast that the active color does not appear,
but it will take longer if there is a problem finding/loading
the browser or URI (e.g. for a File). */
public void browse() {
setForeground(activeColor);
setBorder(activeBorder);
try {
Desktop.getDesktop().browse(target);
} catch(Exception e) {
e.printStackTrace();
}
setForeground(standardColor);
setBorder(standardBorder);
}
/** Browse to the target. */
public void actionPerformed(ActionEvent ae) {
browse();
}
/** Browse to the target. */
public void mouseClicked(MouseEvent me) {
browse();
}
/** Set the color to the hover color. */
public void mouseEntered(MouseEvent me) {
setForeground(hoverColor);
setBorder(hoverBorder);
}
/** Set the color to the standard color. */
public void mouseExited(MouseEvent me) {
setForeground(standardColor);
setBorder(standardBorder);
}
public void mouseReleased(MouseEvent me) {}
public void mousePressed(MouseEvent me) {}
/** Set the color to the standard color. */
public void focusLost(FocusEvent fe) {
setForeground(standardColor);
setBorder(standardBorder);
}
/** Set the color to the hover color. */
public void focusGained(FocusEvent fe) {
setForeground(hoverColor);
setBorder(hoverBorder);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
File f = new File(".","LinkLabel.java");
/* Filename must be constructed with a canonical path in
order to successfully use Desktop.browse(URI)! */
f = new File(f.getCanonicalPath());
JPanel p = new JPanel(new GridLayout(0,1));
URI uriFile = f.toURI();
LinkLabel linkLabelFile = new LinkLabel(uriFile);
linkLabelFile.init();
p.add(linkLabelFile);
LinkLabel linkLabelWeb = new LinkLabel(
new URI("http://pscode.org/sscce.html"),
"SSCCE");
linkLabelWeb.setStandardColor(new Color(0,128,0));
linkLabelWeb.setHoverColor(new Color(222,128,0));
linkLabelWeb.init();
/* This shows a quirk of the LinkLabel class, the
size of the text field needs to be constrained to
get the underline to appear properly. */
p.add(linkLabelWeb);
LinkLabel linkLabelConstrain = new LinkLabel(
new URI("http://stackoverflow.com/"),
"Stack Overflow");
linkLabelConstrain.init();
/* ..and this shows one way to constrain the size
(appropriate for this layout).
Similar tricks can be used to ensure the underline does
not drop too far *below* the link (think BorderLayout
NORTH/SOUTH).
The same technique can also be nested further to produce
a NORTH+EAST packing (for example). */
JPanel labelConstrain = new JPanel(new BorderLayout());
labelConstrain.add( linkLabelConstrain, BorderLayout.EAST );
p.add(labelConstrain);
LinkLabel linkLabelNoUnderline = new LinkLabel(
new URI("http://java.net/"),
"java.net");
// another way to deal with the underline is to remove it
linkLabelNoUnderline.setUnderlineVisible(false);
// we can use the methods inherited from JTextField
linkLabelNoUnderline.
setHorizontalAlignment(JTextField.CENTER);
linkLabelNoUnderline.init();
p.add(linkLabelNoUnderline);
JOptionPane.showMessageDialog( null, p );
} catch(Exception e) {
e.printStackTrace();
}
}
});
}
}
You cannot simply add an actionListener, you need to implement MouseListener, something like this.
If you are looking for Customized JLable with different font and size and mouse action listeners just go through this.
This is fully tested with following tasks
1.JLabel with Image and Text.
2.Jlabel with Mouse Listners.
3.On hover action with image and text replacement.
public class CustomJLabel extends JLabel implements MouseListener
{
private Color color;
private int width=0;
private int height=0;
private ImageIcon normal_icon;
private ImageIcon hover_icon;
private ImageIcon icon_Label;
JLabel label;
private boolean isMatch;
public CustomJLabel(ImageIcon icon,ImageIcon icon1, String text, int i, int j) {
this.normal_icon=icon;
this.hover_icon=icon1;
this.icon_Label=normal_icon;
setFont(new Font("Tw Cen MT", Font.TYPE1_FONT, 16));
setForeground(Color.WHITE);
setOpaque(false);
setHorizontalAlignment( SwingConstants.CENTER );
setText(text);
addMouseListener(this) ;
}
public CustomJLabel(ImageIcon icon,ImageIcon icon1, int i, int j) {
this.normal_icon=icon;
this.hover_icon=icon1;
this.icon_Label=normal_icon;
setText("");
setVerticalAlignment( SwingConstants.CENTER);
setForeground(Color.WHITE);
setOpaque(false);
addMouseListener(this) ;
}
public CustomJLabel(ImageIcon icon,ImageIcon icon1, String text, int i, int j,Font f) {
this.normal_icon=icon;
this.hover_icon=icon1;
this.icon_Label=normal_icon;
this.width=i;
this.height=j;
setFont(f);
setForeground(Color.WHITE);
setOpaque(false);
setText(text);
setVerticalAlignment( SwingConstants.TOP);
addMouseListener(this) ;
}
public int getIconWidth(){
return width;
}
public int getIconHeight(){
return height;
}
#Override
public void paintComponent(Graphics g) {
if(this.width !=0 && this.height!=0){
super.paintComponent(g);
icon_Label.paintIcon(this, g, this.width, this.height);
}
else{
g.drawImage(icon_Label.getImage(),0,0, null);
super.paintComponent(g);
}
}
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent me) {
// TODO Auto-generated method stub
if(hover_icon!=null){
this.icon_Label=hover_icon;
this.repaint();
this.revalidate();
}
else{
this.icon_Label=normal_icon;
this.repaint();
this.revalidate();
}
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
if(normal_icon!=null){
this.icon_Label=normal_icon;
this.repaint();
this.revalidate();
}
else{
this.icon_Label=hover_icon;
this.repaint();
this.revalidate();
}
}
#Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
//Here Usage of custom JLabel
JLabel customLabel;
customLabel=new CustomLabel(imageicon1,imageicon2,text,0,0)
//Here
Imageiocn1= Initial icon for JLabel.
Imageicon2= Onhover image for JLabel.
Text = Some String for setting name for JLabel.