I have a JLabel (with an icon) and I would like to translate this JLabel when the JLabel is clicked. I have added a mouseListener to the JLabel however I didn't come up with anything on how I can execute a translation from coordinates (x, y) to cordinates (x', y')
class MyMouseListener extends MouseAdapter {
#Override
public void mouseClicked(MouseEvent e){
final JLabel label = (JLabel) e.getSource();
System.out.println("Player hit label -> " + label.getName() );
// Code for translating JLabel
}
}
As far as translating (ie moving) your JLabel:
First, you must make sure that the layout manager of its parent is set to null, or uses a customized layoutmanager that can be configured to do your translation.
Once you have that in place, it's a simple matter:
public void mouseClicked(MouseEvent ae) {
JLabel src = (JLabel) ae.getSource();
src.setLocation(src.getLocation().x + delta_x, src.getLocation().y + delta_y);
src.getParent().repaint();
}
Related
I'm building a UI in Java. I want to create new components, like a JLabel, using a button. So every time I click a button it creates a new JLabel and places them in a specific JPanel.
Then, I want to be able to do some things with the labels based on how the user clicks on them.
With a left mouse press I want them to be able to drag the labels around the screen.
With a right mouse click I want to be open a new window where certain data can be entered, tied to the label (which might involve dynamically creating variables).
I've been toying around with some code I've Googled around for. I can get a button to create new labels in a panel, but when I try to get them to drag, I can only get one label at a time to appear, and after a second button press, moving the label isn't smooth, it jumps around.
I haven't even tried to implement any of the right mouse click things yet. If anyone can point me in the right direction, I'd appreciate it.
public class Testing {
JFrame frame;
//Launch the application.
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
Testing window = new Testing();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
//Create the application.
public Testing() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
JPanel area;
JButton btnCreate;
JLabel dragLabel;
frame = new JFrame();
frame.setBounds(100, 100, 511, 542);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
frame.setVisible(true);
area = new JPanel();
area.setBounds(10, 11, 477, 404);
frame.getContentPane().add(area);
area.setLayout(new BorderLayout());
btnCreate = new JButton("Create Label");
dragLabel = new JLabel("Drag Me");
btnCreate.setBounds(10, 425, 477, 67);
frame.getContentPane().add(btnCreate);
btnCreate.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
area.add(dragLabel);
area.revalidate();
DragListener drag = new DragListener();
dragLabel.addMouseListener(drag);
dragLabel.addMouseMotionListener(drag);
}
});
}
}
class DragListener extends MouseInputAdapter
{
Point location;
MouseEvent pressed;
public void mousePressed(MouseEvent me) {
pressed = me;
}
public void mouseDragged(MouseEvent me)
{
if(SwingUtilities.isLeftMouseButton(me)){
Component component = me.getComponent();
location = component.getLocation(location);
int x = location.x - pressed.getX() + me.getX();
int y = location.y - pressed.getY() + me.getY();
component.setLocation(x, y);
}
}
}
EDIT - I'm fairly certain the primary issue is in how the JLabel itself is being added to the panel. Every time the button is being pushed it's adding the same label over again, and this is gumming up the works.
Unfortunately, I'm not sure how to deal with that. I've done a bit more digging, and since dynamic variables aren't possible, I'm going to have to use an array or a map or some sort. With that, it appears I can declare arrays of components. Would something like that be necessary for my purposes?
Really odd stuff in your code. I don't want to go everything, and I'm not an expert by any stretch of the imagination, but I tried to remove redundant or contradictory stuff. I suspect a part of what you did was just copy pasting bits without really fitting them into the code.
Anyway, you needed to create the label inside the listener, so that it creates a new one everytime you click. Otherwise you only ever create one label and just reuse the same everytime.
I implemented a dialog on right click to enter the label name, don't know what you wanted to do but at least it detects right clicks.
Also in general it's easier to use layout managers instead of hardcoding everything. Here you had a borderlayout but were ignoring it.
class Main {
//Launch the application.
public static void main(String[] args) {
DrageableLabel window = new DrageableLabel();
}
}
public class DrageableLabel {
public DrageableLabel() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
JFrame frame = new JFrame();
Container area = frame.getContentPane();
area.setLayout(new BorderLayout());
JButton btnCreate = new JButton("Create Label");
btnCreate.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
/*
This is where you create your new window
for now I've added a dialog that takes a string parameter and creates a label with that string
I moved the method code to create a new drageable label outside the actionlistener to make it less confusing and reuseable
Either build w-e you want directly in here
or call a method that does it (which I prefer)
*/
String string = JOptionPane.showInputDialog(frame, "Enter your message", "Messages", JOptionPane.CANCEL_OPTION);
addDrageableLabel(string, area);
} else if (SwingUtilities.isLeftMouseButton(e)) {
addDrageableLabel("Drag me", area);
}
}
});
area.add(btnCreate, BorderLayout.SOUTH);
frame.setBounds(100, 100, 511, 542);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
// This is the method that creates and adds a drageable label
public void addDrageableLabel(String labelName, Container container) {
JLabel dragLabel = new JLabel(labelName);
container.add(dragLabel, BorderLayout.CENTER);
container.validate();
DragListener drag = new DragListener();
dragLabel.addMouseListener(drag);
dragLabel.addMouseMotionListener(drag);
}
}
class DragListener extends MouseInputAdapter {
Point location;
MouseEvent pressed;
#Override
public void mousePressed(MouseEvent me) {
pressed = me;
}
#Override
public void mouseDragged(MouseEvent me) {
Component component = me.getComponent();
location = component.getLocation(location);
int x = location.x - pressed.getX() + me.getX();
int y = location.y - pressed.getY() + me.getY();
component.setLocation(x, y);
}
}
I want to set the icon on a label when button pressed once if pressed twice it will remove i have used label.setIcon(null); but it is not working fine for me.
public void actionPerformed(ActionEvent e) {
if (!"submit".equals(e.getActionCommand()))
{
JButton button = (JButton) e.getSource();
int X = button.getLocation().x;
int Y = button.getLocation().y;
JLabel tick=new JLabel();add(tick);
tick.setBounds(X+400,Y+15,50,50);
if(arr.contains(e.getActionCommand()))
{
tick.setIcon(null);
arr.remove(e.getActionCommand());
}
else
{
image=new ImageIcon(imageList[0]);
tick.setIcon(image);
arr.add(e.getActionCommand());
}
Don't recreate JLabel and don't add it on each click
JLabel tick=new JLabel();
add(tick);
Create class' field instead and create the label once. If it's initialized just tick.setIcon(null).
How can I remove OR change colour of the border surrounding these tabs?
ALSO, is it possible to have the tab text change colour when the mouse is hovering over it?
Is it possible to have the tab text change colour when the mouse is
hovering over it?
As stated in this answer you can set a custom component for rendering the tab title, through JTabbedPane.setTabComponentAt(int index, Component component) method. So you can do something like this:
final JTabbedPane tabbedPane = new JTabbedPane();
MouseListener mouseListener = new MouseAdapter() {
Color defaultColor;
#Override
public void mouseEntered(MouseEvent e) {
JLabel label = (JLabel)e.getSource();
defaultColor = label.getForeground();
label.setForeground(Color.BLUE);
}
#Override
public void mouseExited(MouseEvent e) {
JLabel label = (JLabel)e.getSource();
label.setForeground(defaultColor);
}
#Override
public void mouseClicked(MouseEvent e) {
JLabel label = (JLabel)e.getSource();
Point point = SwingUtilities.convertPoint(label, e.getPoint(), tabbedPane);
int selectedTab = tabbedPane.getUI().tabForCoordinate(tabbedPane, point.x, point.y);
switch(e.getButton()){
case MouseEvent.BUTTON2: tabbedPane.removeTabAt(selectedTab); break;
default: tabbedPane.setSelectedIndex(selectedTab);
}
}
};
JLabel tab1 = new JLabel("Tab1");
tab1.addMouseListener(mouseListener);
tabbedPane.addTab(null, new JPanel());
tabbedPane.setTabComponentAt(0, tab1);
How can I remove OR change colour of the border surrounding these
tabs?
It's up to the Look and Feel decide the border color in this case. You should look into the L&F default properties and see if it's allowed change this color. For instance you could execute the following code to see L&F default properties (of course after setting the L&F):
for(Object key : UIManager.getLookAndFeelDefaults().keySet()){
System.out.println(key + " = " + UIManager.get(key));
}
I'm trying to add several JLabels to a JPanel along with mouse listeners using a loop. These JLabels are going to have mouse listeners so that they change their icon when clicked (Using label.setIcon()). However, I only want to have one "selected" at a time. So, I need them to know when another label is clicked so it knows to turn itself off before the new label gets selected. However, my problem is that because I'm adding these labels with a loop they all have the same MouseListener.
Can anyone teach me a simple way to accomplish this?
This is a short example, how you could implement it (please note, that I didn't use the icon, but change the label instead):
public class MouseListenerExample extends JFrame {
public static class MyMouseListener extends MouseAdapter {
private static final Collection<JLabel> labels = new ArrayList<JLabel>();
private final JFrame frame;
public MyMouseListener(JFrame frame, JLabel label) {
this.frame = frame;
labels.add(label);
}
#Override
public void mouseClicked(MouseEvent e) {
for (JLabel label : labels) {
String text = label.getText();
if (text.startsWith("X ")) {
label.setText(text.substring(2));
}
}
JLabel currentLabel = (JLabel) e.getComponent();
currentLabel.setText("X " + currentLabel.getText());
}
}
public MouseListenerExample() {
super("MouseListener Example");
Container c = getContentPane();
c.setLayout(new FlowLayout());
for (int i = 0; i < 10; i++) {
JLabel jLabel = new JLabel("Label " + i);
c.add(jLabel);
jLabel.addMouseListener(new MyMouseListener(this, jLabel));
}
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new MouseListenerExample();
}
}
The main idea is, that you create a new MouseListener for each label, but keep a list of labels outside of each listener's scope (in this example I just use a static variable, but you could also have a field containing the list of labels in the frame.
I'm looking to add interactivity to an image but cannot see a way off adding a mouselistener to it. I would like to get the X & Y of where whas clicked on the image.
The Flow if the image is:
tileset = new ImageIcon("xx.png"); //ImageIcon Image that wants to be clicked
label.setIcon(tileset); // assigned to a label
panel.add(label); //assigned to a panel
tileScrollPane = new JScrollPane(panel); // Assigned to a scrollable pane
frame.add(tileScrollPane, BorderLayout.CENTER); // then onto a JFrame
You should be able to add a MouseListener to the label:
label.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent event) {
// Handle click - coordinates in event.
}
});