I would like to get the (Graphics g) when the WorldPanel is shown. Thanks to stackoverflow I saw the answer where should I use the getGraphics method (ComponentListener.componentShown), but somehow my listener couldn't catch the componentShown.
What did I wrong ? At the bottom of the code snippet the "hello" can't not be displayed.
public class MainPanel extends javax.swing.JPanel implements ComponentListener {
private CWorldPanel WorldPanel; // extends JPanel
private void initGUI() {
try {
...
this.setLayout(thisLayout);
{
WorldPanel = new CWorldPanel();
WorldPanel.addComponentListener(this);
...
#Override
public void componentShown(ComponentEvent e) {
System.out.println("hello");
}
See my explanation and thanks at the bottom of the page (cscsaba)
If you want to get the Graphics object in order to paint on your component as soon as it is visible, don't. Simply override the paintComponent method of the object to be shown, and paint in there.
(I have no idea why your ComponentListener does not work, and can't try since your example is incomplete.)
Related
I have a problem when trying to draw some elements using paint method in Swing.
As title says, my whole frame collapses and does some weird repeating.
I made a separate JPanel so I can manipulate drawn shapes:
public class PanelPovrsina extends JPanel{
private ArrayList<Oblik> listaOblika;
public PanelPovrsina() {
// svi oblici
this.listaOblika = new ArrayList<Oblik>();
this.listaOblika.add(new Kvadrat(new Tacka(50, 50), 50, "zuta", "crvena"));
this.setBackground(Color.WHITE);
this.setVisible(true);
}
public void paint(Graphics g) {
if(this.listaOblika.isEmpty()) return;
Iterator<Oblik> it = this.listaOblika.iterator();
while(it.hasNext()) {
it.next().crtajUBoji(g);
}
repaint(); // this causes problems!
}
public ArrayList<Oblik> getListaOblika() {
return this.listaOblika;
}
}
Here is the frame with this code:
And here it is without repaint method:
No, I know repaint method is essential in order to dynamically add shapes and actually draw, but I can't make this work correctly.
Also, as you can see from the code above, background of panel is set to white, but my frame would'n render it.
Hope there is enough information to solve my problem, if not, I will add code of my JFrame!
Thank you!
You should never override the paint method, as it handles a number of other things behind the scenes. You should override paintComponent instead.
As #Joe C answered, I should have been using paintComponent method, not paint! Working code:
public class PanelPovrsina extends JPanel{
private ArrayList<Oblik> listaOblika;
public PanelPovrsina() {
// svi oblici
this.listaOblika = new ArrayList<Oblik>();
this.listaOblika.add(new Kvadrat(new Tacka(50, 50), 50, "zuta", "crvena"));
this.setBackground(Color.PINK);
this.setVisible(true);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Oblik obl : this.listaOblika) {
obl.crtajUBoji(g);
}
repaint();
}
public ArrayList<Oblik> getListaOblika() {
return this.listaOblika;
}
}
im wondering how a jcomponent gets painted on the screen, is it painted inside paintComponent() from Graphics? Or is it painted separately. Im asking this because its weird how a jbutton changes color on mousehover even though repaint() is never called.
Thanks for your time.
Components are painted with their paint method. repaint is just a useful method that will call paint at some point in the near future on the Event Dispatch Thread.
When the mouse enters a JButton, the following method is called (for JButtons with a default UI):
public void mouseEntered(MouseEvent e) {
AbstractButton b = (AbstractButton) e.getSource();
ButtonModel model = b.getModel();
if (b.isRolloverEnabled() && !SwingUtilities.isLeftMouseButton(e)) {
model.setRollover(true);
}
if (model.isPressed())
model.setArmed(true);
}
ButtonModel.setRollover will fire a ChangeEvent, which is handled by AbstractButton in the following way:
public void stateChanged(ChangeEvent e) {
Object source = e.getSource();
updateMnemonicProperties();
if (isEnabled() != model.isEnabled()) {
setEnabled(model.isEnabled());
}
fireStateChanged();
repaint();
}
So repaint is called when the mouse enters a JButton.
..a jbutton changes color on mousehover even though repaint() is never called.
Sure it is. And this code is evidence of that. Of course, it is not evidence on a Kindle Fire that most probably has no JRE, but then, a Kindle Fire is an entirely inappropriate tool to be using to communicate to a Q&A site while discussing technical points of a programming language that does not run on the device.
import javax.swing.*;
public class ButtonRepaint {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
JButton b = new JButton("Hover Over Me!") {
#Override
public void repaint() {
super.repaint();
System.out.println("Repaint");
}
};
JOptionPane.showMessageDialog(null, b);
}
};
SwingUtilities.invokeLater(r);
}
}
Note that the paint() method that gets called belongs to the button's UI delegate, typically derived from BasicButtonUI. There's an example here using MetalButtonUI.
Could you tell me what methods are called upon a JFrame/JDialog after you resize it manually?
( after you resize it using the mouse cursor, while the frame is visible on the screen). I noticed that my JDialog is not valid eventhough I call validate() or revalidate() upon it, but after I resize it a bit, my frame becomes valid.
I think it is java.awt.event.ComponentListener
The listener interface for receiving component events. When the
component's size, location, or visibility changes, the relevant method
in the listener object is invoked, and the ComponentEvent is passed to
it.
For example:
public class MyFrame extends JFrame implements ComponentListener {
#Override
public void componentResized(ComponentEvent e) {
// re compute?
repaint();
}
}
With this code I am able to resize the width, height of 3 tables.
container.addControlListener(new ControlAdapter() {
#Override
public void controlResized(ControlEvent e) {
tableJobs.setBounds(20, 143,container.getBounds().width-40, container.getBounds().height-20);
tableMessages.setBounds(20, 143,container.getBounds().width-40, container.getBounds().height-20);
tableSplfs.setBounds(20, 143,container.getBounds().width-40, container.getBounds().height-20);
}
});
I'm puzzled with a strange mouse listener behavior.
First, I defined an interface :
public interface GeniusField {
public void setEdited(Boolean b);
public void addMouseListeners();
public void addKeyListeners();
public String getStringValue();
}
then, I implement this interface :
public class GeniusComboField extends JComboBox implements GeniusField {
public GeniusComboField() {
super();
//blabla
addMouseListeners();
addKeyListeners();
}
#Override
public void addMouseListeners() {
System.out.println("ADD LISTENTER");
this.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
System.out.println("mouse mouse");
}
});
}
}
And for some reason, nothing is triggered when I click on my combobox (but I get the "ADD LISTENER" output).
I don't see what is happening.
Can someone help?
In Java Swing JComboBox don't receive the mouse events. It's the components within that do it. Try something like:
for (int i=0; i<this.getComponentCount(); i++) {
this.getComponent(i).addMouseListener(this);
}
Then make your class implements MouseListener.
Or you can override the method to add object to your combobox and call your addMouseListener() method. Like that each object will have a listener.
JComboBox is a compound component, which means it's made up of two or more other components.
You shouldn't register listeners for low-level events on compound components because they wont capture them properly.
You need to implement ActionListener to get it to work.
public class GeniusComboField extends JComboBox implements ActionListener, GeniusField {
. . .
}
More information about this is available in the swing trail of the Java tutorial.
I tried this code. it seems to work just fine. Problem may be where your adding this combo box. The mouse listener will be for the combo box itself, not the items in it.
Somebody has to implement MouseListener( may be GeniusComboField ).
something like this.
public class GeniusComboField extends JComboBox implements GeniusField, MouseListener
I've extended a JList to provide two separate functionalities, toolTipText for items, and right-click options. Both work separately, but when I try to use them together, the MouseMoved events aren't being recognized? Below are the guts of my new listener methods. How should I be negotiating these various events?
public class JListTT extends javax.swing.JList {
public JListTT() {
super();
addMouseListener(new ttListener());
...
class ttListener extends MouseAdapter {
public void mouseMoved(MouseEvent e) {
String nodeID = bldItemNodeID();
theList.setToolTipText(nodeID);
}
public void mousePressed(MouseEvent ev) {check(ev); }
public void mouseReleased(MouseEvent ev) {check(ev); }
public void mouseClicked(MouseEvent ev) {check(ev); }
public void check(MouseEvent ev) {
if (ev.isPopupTrigger()) {
theList.setSelectedIndex(theList.locationToIndex(ev.getPoint()));
menu.show(theList, ev.getX(), ev.getY());
}
}
}
You add the ttListener object as a MouseListener, but I don't see you adding the ttListener object as a MouseMotionListener. For example:
ttListener myMouseadapter = new ttListener();
addMouseListener(myMouseadapter);
addMouseMotionListener(myMouseadapter);
I did not test this myself, but looking at the javadoc of JList the tooltip functionality is available out of the box. The javadoc of JList#getTooltipText clearly states
Overrides JComponent's getToolTipText method in order to allow the
renderer's tips to be used if it has text set.
So if your ListCellRenderer returns a Component in the getListCellRendererComponent method which has a tooltip it will be displayed by the JList without the need of a listener.
there's not necessarily a need for a low-level approach as a custom mouse-/motionListener:
as to a per-cell tooltip, see #Robin's answer
as to a context menu, JComonent has a property componentPopupMenu: using that will cope with opening the menu on keyboard short-cut automatically
"not necessarily" because you seem to rely on the cell being selected on right click. If so, you would still need a MouseListener to trigger the selection (after decade long debates, Swing doesn't - which seems to be unusual in current native apps ;-)
You can achieve it by using mouseDragged
YourClass extends JPanel implements MouseListener{
......
#Override
public void mouseDragged(MouseEvent e) {
//code go here
}
}