Get value on clicking jprogressbar - java

I am trying to make a player in java.
Have made a seekbar using jprogressbar as shown in this link in Andrew Thompson's answer,
I have been able to add a mouselistener and detect click on jprogressbar, but how do I get the selected value of jprogressbar to which I will seek my bar to?
I tried,
progressBar.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
int v = progressBar.getSelectedValue();
jlabel.setText("----"+v);
}
});
But didn't work as I expected, could not even find anything on internet.
Please help me. Thanks for your time and effort, really appreciated.

You would probably have to calculate the location on the JProgressBar based solely on the mouse click co-ordinates. You could essential do this:
progressBar.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
int v = progressBar.getValue();
jlabel.setText("----"+v);
//Retrieves the mouse position relative to the component origin.
int mouseX = e.getX();
//Computes how far along the mouse is relative to the component width then multiply it by the progress bar's maximum value.
int progressBarVal = (int)Math.round(((double)mouseX / (double)progressBar.getWidth()) * progressBar.getMaximum());
progressBar.setValue(progressBarVal);
}
});

Related

Click on progressbar to seek MediaPlayer

I have a music player that has a ProgressBar that has a max value of mediaPlayer.getTotalDuration().toSeconds()
Recently I have been trying to make a MouseListener to seek the mediaPlayer to the returned X value when the ProgressBar is clicked on a certain position.
The problem: I click on the ProgressBar and it appears to be receiving milliseconds so I multiply it by 1000 so it seeks to the corresponding second-count.
This works accurately for some music/mp3s but for shorter ones, or some longer ones, the ProgressBar only jumps to the nearest possible position, or jumps to some other position, completely inaccurate due to the * 1000 calculation of the X value. (Below I've tried someone's suggestion for another answer to calculate the X value to seconds and I have also tried setting the ProgressBar value and setting that value to where the mediaPlayer is.)
"int point" is where I receive the X value.
Code:
progressBar.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent mouseClick) {
try{
progressBar.setMaximum((int)mediaPlayer.getTotalDuration().toSeconds());
int point = (int)Math.round(((double)mouseClick.getX() / (double)progressBar.getWidth()) * progressBar.getMaximum()); // previously tried "* 1000".
Duration pointDuration = new Duration(point);
mediaPlayer.seek(pointDuration);
} catch (Exception e7){
//
}
}
});
(Unfortunately that calculation is even worse.)
What sort of calculation should I use to correctly seek to the clicked position?
You have to choose your units wisely, and to make them appear in your code. What I usually do is to limit the progressbar to a [0.0,1.0] range, i.e. a percentage with double arithmetic.
When you receive a mouse click event you convert the event position in that [0,1] range.
Two things are needed:
the width (in pixels) of the progressbar
the x-coordinate of the mouseclick relative to progressbar component
And you have an accurate point (note toMilliseconds):
double dx = evt.getX();
double dwidth = progressBar.getWidth();
double progression = (dx / dwidth);
int milliseconds = (progression * mediaPlayer.getTotalDuration().toMilliseconds())
Duration duration = new Duration(milliseconds);
mediaPlayer.seek(duration);
Well 1st mistake you make is setting progressBar maximum value when you click the progress bar. While media is playing and you did not pressed progressBar yet the max value of progres bar is wrong. This value should be set when the mediaPlayer duration is changed. You should add listener to totalDurationProperty change in same method that mediaPlayer got media assigned.
Media media = new Media(filePath);
mediaPlayer = new MediaPlayer(media);
mainMediaView.setMediaPlayer(mediaPlayer);
mediaPlayer.totalDurationProperty().addListener(new ChangeListener<Duration>() {
#Override
public void changed(ObservableValue<? extends Duration> observable, Duration oldValue,
Duration newValue) {
progressBar.setMax(newValue.toSeconds());
}
});
2nd problem is that Slider component and its progress bar have different sizes.
progressBar mouse listener:
progressBar.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent mouseClick) {
try{
double value;
value = (mouseClick.getX()-9) * (progressBar.getMax() / (progressBar.getWidth()-19));
progressBar.setValue(value);
} catch (Exception e7){
}
}
});
You might ask how did -9 and -19 showed up in there. Got those values by trial and error. As Slider component is larger than its progress bar getWidth() returns larger value. That includes gap on both sides of progress bar. -9 is for adjusting click position to gap between slider component and beginning of progress bar. -19 thats slider component width smaller by gaps on both sides of progress bar.

Icon images not loading fast enough

I have an array of JPanel with JLabel with icons that represent a seat at a theater, all of them are generated using loop.
Upon loading the seats, those that are already booked need to have a different image icon. So if(){} check is performed on all the seats to change the label icon if the seat is booked, after they are generated.
But the image icon I have on my disk is not loading fast enough so sometimes the panel adds only to the last one booked or not at all.
Every of those panels that represent the chairs has also MouseListener interfaces added to them. So also on mouse hover or click ImageIcon objects added to the panels are changed, there is too much delay when this happens. I'm thinking that has to do with the images being on the disk!.
How can I load and store those icon images 2,78 KB in size in memory and refer to it in memory, so it wont be delayed reading them?
When a seat is clicked I need to change the label image of that seat and remove mouse listener from that seat. Is there a way to remove the mouse listener to that particular seat without referring to a specific mouse listener. I needed to do that outside of the mouse listener itself!
panel.removeAll();
Does not remove the mouse listener added upon generating the panels.
public void drawSeats(int ammountSeat, int localLength, int localWidth) {
pnlSeatsHolder = new JPanel();
pnlSeatsHolder.setPreferredSize(new Dimension(localLength * 40,localLength * 45));
pnlSeatsHolder.setLayout(new FlowLayout());
for (int d = 0; d <= (ammountSeat); d++) {
imgIconYellow = new ImageIcon("seatYellow.png");
imgIconBlue = new ImageIcon("seatBlue.png");
imgIconRed = new ImageIcon("seatRed.png");
JButton chairs = new JButton();
chairs.setPreferredSize(new Dimension(30, 40));
pnlSeatsHolder.add(chairs);
chairs.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {
for (int i = 0; i < listSeatsObjects.size(); i++) {
if (listSeatsObjects.get(i).equals(e.getSource())) {
/*I need to do this also outside of this method! how can i refer to this MouseListener
* to forexample do the equivalent of chairs.removeMouseListener(this);*/
chairs.removeAll();
chairs.setIcon(imgIconRed);
chairs.repaint();
chairs.removeMouseListener(this);
// send information of the chair somewhere else
}
}
}
public void mouseEntered(MouseEvent e) {
// chairs.setBackground(Color.blue);
chairs.removeAll();
chairs.setIcon(imgIconBlue);
chairs.repaint();
}
public void mouseExited(MouseEvent e) {
// chairs.setBackground(Color.BLACK);
chairs.removeAll();
chairs.setIcon(imgIconYellow);
chairs.repaint();
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
});
}
}
so this is the method it self that draws the seats when called. I did some modification as #AndrewThompson suggested, instead of JPanels i use now JButtons, but what happens is that the images are not loaded at all on to the buttons.. what am i missing? neither on mouse hover either.. tho it does work if i had for example charis.setBackgroundColor(); on hover or click.. so i now i need to rather change the buttons images when clicked and on hover, i've tried chairs.chairs.setRolloverIcon(); and .setIcon(); both not working as well. what is wrong. my images are in the same directory as the class files.. so that cant be the issue..
int localLength, int localWidth is the size of the the rooms that seats will be drawn in. about 1m^2/seat
For three images, load them when the class is initialized and store them as attributes of the class. Of course, each of the 3 images can be used in as many icons as needed.

Java - Mouse out of window

How do I know if the mouse if out of the window I made and from which side it exited. I'm making a classic pong game and when I move my mouse out too fast, the 'thing' stays some pixels in. I'd like it to move to the edge of the window where it exited.
private class MouseMotion extends MouseAdapter{
public void mouseMoved(MouseEvent e) {
super.mouseMoved(e);
int x = e.getX();
p1.move(x);
}
}
and the move function
public void move(int x) {
if (x < 0 ) {
this.x = 0;
}else if(x+width > Main.screenSize.width - 1){
this.x = Main.screenSize.width - width - 1;
} else {
this.x = x;
}
}
I just need to know a way to know if the mouse is out of the window.
Check for MouseListener.mouseExited(MouseEvent).
You might want to take a look this:
Point mouse = MouseInfo.getPointerInfo().getLocation();
This tells you were the pointer is on the screen. No matter if your application has the focus or not. No matter if the pointer in on top of your window or not.
You can use MouseExited() and then get the coordinate from the event generated, using event.getPoint().
Try putting this somewhere where it will get run and getting rid of the MouseMotion class. 'c' is the JComponent that p1 is getting drawn to, I don't know what you called that object in your code. 'running' is some boolean that is set to true. When this code is run, p1 will move according to the mouse until 'running' is set to false.
new Thread(()->{
while(running) {
p1.move(MouseInfo.getPointerInfo().getLocation().getX()-c.getLocationOnScreen());
}
}).start();

Jobjects on top of existing object

so I would like to know if it's possible to put things like buttons, text boxes, words, progress bars, ect, ect, on top of an already existing, in this example, JLabel.
Here is the image of the undercoated frame I made, followed by the snippet of code that is associated with this undercoated frame.
(I dont have 10 reputation, so here is a link to a photo)
http://prntscr.com/15516f
Map.setTitle("Map");
Map.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Map.setUndecorated(true);
Map.setBackground(new Color(0,0,0,0));
Map.setLayout(new FlowLayout());
JLabel Background = new JLabel(new ImageIcon(getClass().getResource("Map.png")));
Background.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
initialClick = e.getPoint();
getComponentAt(initialClick);
}
});
Background.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
// get location of Window
int thisX = Map.getLocation().x;
int thisY = Map.getLocation().y;
// Determine how much the mouse moved since the initial click
int xMoved = (thisX + e.getX()) - (thisX + initialClick.x);
int yMoved = (thisY + e.getY()) - (thisY + initialClick.y);
// Move window to this position
int X = thisX + xMoved;
int Y = thisY + yMoved;
Map.setLocation(X, Y);
}
});
Map.add(Background);
Map.setSize(507,512);
Map.setLocation(0, 100);
Map.setResizable(false);
Map.setVisible(false);
on a side note, and I KNOW this is FlowLayout(), but when I try to add something else, it'll just put itself above, or below my map.
I'd just like to know if I could put things on top of this Map.
Maybe I should put the image in in another way besides the JLabel?
Look into JLayeredPane and similar strategies. See How to Use Layered Panes for more details.

JSlider question: Position after leftclick

Whenever I click a JSlider it gets positioned one majorTick in the direction of the click instead of jumping to the spot I actually click. (If slider is at point 47 and I click 5 it'll jump to 37 instead of 5). Is there any way to change this while using JSliders, or do I have to use another datastructure?
As bizarre as this might seem, it's actually the Look and Feel which controls this behaviour. Take a look at BasicSliderUI, the method that you need to override is scrollDueToClickInTrack(int).
In order to set the value of the JSlider to the nearest value to where the user clicked on the track, you'd need to do some fancy pants translation between the mouse coordinates from getMousePosition() to a valid track value, taking into account the position of the Component, it's orientation, size and distance between ticks etc. Luckily, BasicSliderUI gives us two handy functions to do this: valueForXPosition(int xPos) and valueForYPosition(int yPos):
JSlider slider = new JSlider(JSlider.HORIZONTAL);
slider.setUI(new MetalSliderUI() {
protected void scrollDueToClickInTrack(int direction) {
// this is the default behaviour, let's comment that out
//scrollByBlock(direction);
int value = slider.getValue();
if (slider.getOrientation() == JSlider.HORIZONTAL) {
value = this.valueForXPosition(slider.getMousePosition().x);
} else if (slider.getOrientation() == JSlider.VERTICAL) {
value = this.valueForYPosition(slider.getMousePosition().y);
}
slider.setValue(value);
}
});
This question is kind of old, but I just ran across this problem myself. This is my solution:
JSlider slider = new JSlider(/* your options here if desired */) {
{
MouseListener[] listeners = getMouseListeners();
for (MouseListener l : listeners)
removeMouseListener(l); // remove UI-installed TrackListener
final BasicSliderUI ui = (BasicSliderUI) getUI();
BasicSliderUI.TrackListener tl = ui.new TrackListener() {
// this is where we jump to absolute value of click
#Override public void mouseClicked(MouseEvent e) {
Point p = e.getPoint();
int value = ui.valueForXPosition(p.x);
setValue(value);
}
// disable check that will invoke scrollDueToClickInTrack
#Override public boolean shouldScroll(int dir) {
return false;
}
};
addMouseListener(tl);
}
};
This behavior is derived from OS. Are you sure you want to redefine it and confuse users? I don't think so. ;)

Categories

Resources