Recently, I have been trying to make my gui's look good and part of it is implementing my own titlebar, maximize button, minimize button, etc.
I am having issues on the dragging, I want to be able to drag the JFrame by clicking anywhere in it.
I attempted to create a mousemotionlistener to handle it however it slips when I use it. As in I attempt to drag the window to a location however it appears to be skipping calls to mouseDragged and attempting to call mouseMoved instead.
Here is my code
public class MouseWindowDragManager implements MouseMotionListener{
private JFrame frame;
int prevPosX = -1;
int prevPosY = -1;
public MouseWindowDragManager(JFrame frame){
this.frame = frame;
}
#Override
public void mouseDragged(MouseEvent e) {
int newX = (frame.getLocation().x + (e.getXOnScreen() - prevPosX));
int newY = (frame.getLocation().y + (e.getYOnScreen() - prevPosY));
frame.setLocation(newX, newY);
prevPosX = e.getXOnScreen();
prevPosY = e.getYOnScreen();
}
#Override
public void mouseMoved(MouseEvent e) {
prevPosX = e.getXOnScreen();
prevPosY = e.getProperty("apple.awt.draggableWindowBackground", true);tYOnScreen();
}
}
Recently, I have been trying to make my gui's look good and part of it is implementing my own titlebar, maximize button, minimize button, etc.
Gee, Microsoft and Apple spend millions of dollars to develop GUI's that users can use. They will be disappointed to hear this :)
I want to be able to drag the JFrame by clicking anywhere in it.
Check out Moving Windows for a class that allows you to drag a window around. The example code shows how to use the class by just dragging on your custom title bar. However, if you really want to be able to drag the frame by clicking anywhere then you can register the frame's root pane with the ComponentMover.
Related
I'm trying to drag a jLabel around the screen following the mouse pointer. As I am no expert on GUI programming I'm trying to do it using Netbeans' GUI design facilities.
I click on "events-mousemotion-mousedragged" and then insert the following code:
private void jLabel2MouseDragged(java.awt.event.MouseEvent evt) {
int x=evt.getX();
int y=evt.getY();
jLabel2.setLocation(x, y);
jLabel2.repaint(); }
I don't expect this simple piece of code to work marvels, the issue however is that it behaves in an erratic manner, the jLabel pops up and flickers almost everywhere within its container.
If it's of any help, layout is set to absolute.
Thanks.
As MadProgrammer pointed out, that was the issue. This is my mouse drag method:
private void jLabel2MouseDragged(java.awt.event.MouseEvent evt) {
Point p = SwingUtilities.convertPoint(evt.getComponent(), evt.getPoint(), getContentPane());
int x=p.x;
int y=p.y;
jLabel2.setLocation(x-120, y-120);
jLabel2.repaint();
}
The jLabel now moves smoothly.
My label is roughly 240x240 pixels, so I corrected the coordinates to have the center of the label placed where the mouse pointer is.
Thanks!
I am fairly new to Java programming and want to make a basic game that shows an image when clicked once, a different image when clicked twice and etc.
I know how to do all this but I don't know how to keep track of how any clicks and then do an actions based on how many clicks have been done (Hard to explain, my apologies...)
I ... want to make a basic game that shows an image when clicked once, a different image when clicked twice and etc. I know how to do all this but I don't know how to keep track of how any clicks
As per my comment, give the class with the ActionListener an int field, say called buttonCount, and increment it each time the button is pressed -- inside of the button ActionListener's actionPerformed method: buttonCount++
and then do an actions based on how many clicks have been done (Hard to explain, my apologies...)
In the ActionListener's actionPerformed method change the image displayed. How you change it all depends on how you show it, something that you've yet to show us, and so I can't give you any code.
One way to make it easy is to create an ArrayList of ImageIcons to hold your images (as ImageIcons of course), and then call get(buttonCount) on the ArrayList to get the appropriate ImageIcon and display it in a JLabel via its setIcon(...) method. Make sure that the buttonCount is less than the size of the ArrayList so as not to get an ArrayIndexOutOfBoundsException. One way to do this is to mod your buttonCount by the size of the ArrayList. This will allow you to cycle through your collection of images.
Again, you will want to read the Swing tutorials on how to use JButtons and then break down your big problem into small steps, trying to solve each step one at a time.
Again if you need greater detail and more specific help, then you must show what you've tried and explain in detail what problems you may be having with it. It is my sincere believe and philosophy that you learn most by by forcing your brain to do new and unfamiliar things, by mental effort and sweat. So have at it, you've nothing to lose.
You can count the the mouse clicks in this way. By using an if-else or switch case you can display the images.
public class ButtonStart extends Frame {
private int mouseclicked = 0;
TextField objTextField;
public static void main(String args[]) {
ButtonStart BS = new ButtonStart();
}
public ButtonStart() {
Frame objFrame;
Button objButton;
TextField objTextField;
objFrame = new Frame("Clicking Buttons");
objButton = new Button("Click me!");
objTextField = new TextField("0");
objFrame.addMouseListener(new MyMouseListener());
objFrame.add(objButton);
objFrame.add(objTextField);
objFrame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
}
public class MyMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent me) {
int mouseclicked = me.getClickCount();
objTextField.setText("Mouse clicked this many times:"
+ mouseclicked);
}
}
}
I am changing the bounds of a JPanel using a Timer to get a sliding effect when someone hovers over a particular rectangular area, this is working as expected. There are buttons in the JPanel and they have different MouseEvent behaviors. But SOMETIMES it starts lagging or slides very slowly. Please, can anyone suggest what can I do, to ensure it performs well every time?
EDITED:
The buttonsPanel have button in it. buttonsPanel is added to a JLayeredPane which have bounds as rect. When JLayeredPane or JButton button is hovered mouse events are triggered. Mouse events then triggers the timer to slide the buttonsPanel and bring to it view.
class MyActionListener implements ActionListener {
private static final int frames = 50;
int count = 0;
private final Timer timer = new Timer(1, this);
public void start() {
timer.start();
}
#Override
public void actionPerformed(ActionEvent ae) {
if (count >= frames) {
timer.stop();
} else {
count = count + 1;
buttonsPanel.setBounds(hidden_width - hidden_width * count / frames, 0, hidden_width, frameHeight);
}
}
}
class MyMouseListener extends MouseAdapter {
private MyActionListener timerListener;
#Override
public void mouseEntered(final MouseEvent event) {
final Color color = new Color(50, 50, 50);
if (event.getSource() instanceof JButton) {
final JButton button = (JButton) event.getSource();
button.setBackground(color);
buttonsPanel.setVisible(true);
} else if (!buttonsPanel.isVisible()) {
buttonsPanel.setVisible(true);
timerListener = new MyActionListener();
timerListener.start();
}
}
#Override
public void mouseExited(final MouseEvent event) {
Point point = new Point(0, 0);
if (event.getSource() instanceof JButton) {
final JButton button = (JButton) event.getSource();
point = button.getLocation();
button.setBackground(Windows8GUI.color);
}
Rectangle rect = new Rectangle(0, 0, hidden_width, frameHeight);
if (!rect.contains(point.x + event.getX(), point.y + event.getY())) {
buttonsPanel.setVisible(false);
buttonsPanel.setBounds(0, 0, hidden_width, frameHeight);
}
}
}
The primary issue is you are assuming that you have control over the paint engine. You don't, in fact, the paint engine is at the mercy of the OS. This means that you can jump up and down all you like, but until the OS and Java's paint engine are ready, nothing will happen.
In fact, if you call repaint repeatedly in quick succession you can find yourself flooding the paint engine with requests, slowing it down even further.
While not a solution to the whole problem, it will make your life vastly simpler take a look at the TimingFramework or Trident.
They are "animation" frameworks designed to take out the guess work and make your life easier. I personal use TimingFramework for all my animation and it works well.
The timing frameworks work on a % over time. That is, you give it a time for a cycle and the frameworks will return a % value based on how far through that cycle they are. You can apply interpolations, allowing you to effect how fast a portion of the animation will play.
Trident has also been designed to provide the means to call other methods on your behalf, so it could set the bounds of the button pane for you, based on values you supply it.
In fact, if you call repaint repeatedly in quick succession you can find yourself flooding the paint engine with requests, slowing it down even further.
I think this is the real problem. Try increasing the delay between the timer events from 1 to 10-50 and it should run a lot better.
For a lot of how-tos for building those (and a lot of other) effects, I can only recommend the Book Filthy Rich Clients. On this page you also find a lot of examples for those effects handled in the book.
Okay, so in this program I'm making, users will be able to create shortcuts to their favorite apps on their computer. My program will be kind of like a hub, I guess, for apps. I have a small problem though, which involves two classes: AppButton and AppButtonContainer. They both implement MouseListener, but AppButton extends JComponent and AppButtonContainer extends JPanel. Basically, when an AppButton is clicked, it sets a draws the border in a different color to make it look selected. Otherwise, it sets the border to the background color. When you double click it, it opens up the application specified. I have a method in AppButton to remove the focus, and therefore setting the border to the background color. In AppButtonContainer, there is a bit of code so that when, the panel is clicked, it removes the focus from the AppButton.
That's my problem, though. The AppButtonContainer doesn't realize that it's clicked. I'm thinking it has something to do with top level containers or something, but I'm not sure. Can anybody help?
EDIT: I found out that I didn't put the addMouseListener(this) in the constructor of the AppButtonContainer. Thank you for everyone who helped me clear up this problem and give me tips along the way :)
AppButtonContianer:
public class AppButtonContainer extends JPanel implements MouseListener {
private static final long serialVersionUID = 6485231881729120957L;
public List<AppButton> appButtons;
private static final Color BACKGROUND_COLOR = new Color(18, 18, 18);
public AppButtonContainer(List<AppButton> buttons) {
this.appButtons = buttons;
setLayout(new GridLayout(5, 5, 20, 20));
addButtonsToPane();
}
private void addButtonsToPane() {
List<AppButton> buttons = this.appButtons;
for (int i = 0; i < buttons.size(); i++) {
this.add(buttons.get(i));
}
}
private void removeAllButtonFocus() {
for (int i = 0; i < this.appButtons.size(); i++) {
this.appButtons.get(i).removeFocus();
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(BACKGROUND_COLOR);
repaint();
}
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("Pane Clicked");
removeAllButtonFocus();
}
...Other MouseEvent methods
You can solve the problem at hand by putting addMouseListener(this) in the constructor for your AppButtonContainer class. Otherwise, it'll never pick up mouse events.
Generally, though, it's not good to turn your classes into mouselisteners like that. Perhaps try making an inner class to listen for mouse events and pass them to the AppButtonContainer instead.
I know how to do action listeners for button clicks in/on swing, but I have this class which does some stuff but I want it a function/event that when a button is clicked it runs a method similiar to the PaintComponent below... (draws a line)
class CustomPanel extends JPanel {
private int destx = 100;
private int desty = 100;
private int startx = 0;
private int starty = 0;
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(startx, starty, destx, desty);
}
}
How would I call this paintcomponent (Or a similar one which draws a line) from a action listener?
Here is my actionlistener: (Its on GUI.java while the code above is on CustomPanel.java)
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == loginButton)
{
//Does other stuff but removed for simplifying
CustomPanel cp = new CustomPanel();
}
}
Thanks alot,
Your question didn't make sense to me in your last posting and it still doesn't make sense to me in this posting.
You still haven't posted a SSCCE that attempts to demonstrate what you want to do.
If you have a "login panel", typically that is done by creating a modal JDialog.
If you are trying to draw a diagonal across the top of all components in the frame, then you would need to use a Glass Pane or a Layered Pane.
Read the section from the Swing tutorial on How to Use Root Panes for examples and more detailed information.
You need to add it to gui. Something like this:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
parentPanel.add(new CustomPanel());
parentPanel.revalidate();
parentPanel.repaint();
}
});
But if you only want to draw a line on the current container that's another thing...
Simply adding your CustomPanel to any other JComponent and updating the UI should do the trick. Swing takes care of all the painting for you.
Here is a reslly useful guide to swing painting;
http://java.sun.com/products/jfc/tsc/articles/painting/#paint_process