Results 1 to 20 of 20
  1. #1
    willemjav is online now Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,019
    Rep Power
    8

    Default Scaling-ache and mouse dragging

    Scaling-ache and mouse dragging

    Imagine a class that inherences of JPanel (that’s the way to say it, I believe). I’d like to get a frame (drawn in a graphical context in a central position of the panel. The panel will be added in another class (details I´ll discuse some later). But the code I wrote is acting strangely:

    public void setframeSize (int framew, int frameh) {
    this.framew = framew; // the frame size is set in other class
    this.frameh = frameh;
    framex = getWidth()/2 - (framew/2);
    framey = getHeight()/2 - (frameh/2);


    }


    public void drawframe(Graphics g) {
    g.setColor(Color.RED);
    g.drawRect(framex, framey, framew, frameh);
    g.drawRect(framex-1, framey-1, framew, frameh);
    g.drawRect(framex-2, framey-2, framew, frameh);
    }

    The getWidth()/getHeight() should deliver the size of the JPanel, Correct?
    But the only way to make the frame (the size of the applet) appear correctly is to add the code in bold to the second method which is part of the same class. I do not understand why that is, because both methods take through get() the size from the same JPanel, or not?

    (once the frame is set, the dragging will follow...have the code working allready but still some stuff to solve, more questions will follow)

    willemjav

  2. #2
    willemjav is online now Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,019
    Rep Power
    8

    Default

    small addition:
    the constructor of the class sets the pref size of the JPanel
    public Editimages() {

    imagepanelX = 800;
    imagepanelY = 500;
    setPreferredSize(new Dimension(imagepanelX, imagepanelY));

    etc.

  3. #3
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    Java Code:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.MouseInputAdapter;
    
    public class FramingTest extends JPanel {
        int framex;
        int framey;
        int framew;
        int frameh;
    
        public void setFrame(Point p1, Point p2) {
            framew = Math.abs(p1.x - p2.x);
            frameh = Math.abs(p1.y - p2.y);
            // Center frame in this component view.
            // But this won't look right while dragging.
            //framex = (getWidth() - framew)/2;
            //framey = (getHeight() - frameh)/2;
            // Calculate x and y for more intuitive
            // and accurate display of dragged shape:
            framex = (p1.x < p2.x) ? p1.x : p2.x;
            framey = (p1.y < p2.y) ? p1.y : p2.y;
            repaint();
        }
    
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D)g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setStroke(new BasicStroke(3f));
            g2.setColor(Color.RED);
            g2.drawRect(framex, framey, framew, frameh);
        }
    
        public static void main(String[] args) {
            FramingTest test = new FramingTest();
            Framer framer = new Framer(test);
            test.addMouseListener(framer);
            test.addMouseMotionListener(framer);
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(test);
            f.setSize(400,400);
            f.setLocation(200,200);
            f.setVisible(true);
        }
    }
    
    class Framer extends MouseInputAdapter {
        FramingTest component;
        Point start;
        boolean dragging = false;
    
        public Framer(FramingTest test) {
            component = test;
        }
    
        public void mousePressed(MouseEvent e) {
            start = e.getPoint();
        }
    
        public void mouseDragged(MouseEvent e) {
            component.setFrame(start, e.getPoint());
        }
    }

  4. #4
    willemjav is online now Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,019
    Rep Power
    8

    Default

    Yes I noticed that when dragging things get worse

  5. #5
    willemjav is online now Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,019
    Rep Power
    8

    Default

    but getWidth() provides the width of the active component which is JPanel or not? By putting the getWidth() at different ¨places¨ in the class (different methods) gives different results which makes no since to me.

  6. #6
    willemjav is online now Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,019
    Rep Power
    8

    Default

    I am figuring out a dragging position algoritme (difficult word to write)
    myself but of course study yours carefully
    ops this is ofcourse not a java chat

  7. #7
    willemjav is online now Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,019
    Rep Power
    8

    Default

    good nigth from spain

  8. #8
    willemjav is online now Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,019
    Rep Power
    8

    Default Timing

    Timing is an important issue. The two framesize variables framew/ frameh weren´t set at the right time. So I learned that the constructor of the second class is the place to trigger some important things like the frame size of the applet. The framesize enters now as parameter of the constructor. The constructor is called first when creating a object of that class. I noticed that I can not use the getWidth() in the constructor (probably the main component JPanel is not yet set?).

    public Editimages(int framew, int frameh) { // the second class consructor

    imagepanelX = 800;
    imagepanelY = 500;
    setPreferredSize(new Dimension(imagepanelX, imagepanelY));
    this.framew = framew;
    this.frameh = frameh;
    framex = imagepanelX/2 - (framew/2);
    framey = imagepanelY/2 - (frameh/2);
    infotextPanel = new JTextArea();
    infotextPanel.setEditable(false);
    infotextPanel.setLineWrap(true);
    infotextPanel.setMinimumSize(new Dimension(50, 50));
    infotextPanel.setMaximumSize(new Dimension(50, 50));
    infotextPanel.setOpaque(false);
    setLayout(null);
    add(infotextPanel);
    addMouseListener(this);
    addMouseMotionListener(this);

    etc.

    The above delivers the framew/h as the fixed size and the framex/h as the fixed central position. These four variables could be the basis of the dragging?
    Probably not… I’ll continuo studying hardwire´s code.

    Bytheway I learn by trail and error. The small panel

    JOptionPane.showMessageDialog(infoPane, "x y " + framex +" / "+ framey + " frame w/h " + frameh + " / " + framew);

    Is extremely useful to me. I plug this little code in where ever I want to stop the program and to see what’s going on at that specific spot. I know there are more sophisticated and professional ways…. But for the moment, hardwired, this works for me.

    willemjav

  9. #9
    willemjav is online now Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,019
    Rep Power
    8

    Default my dragging code

    Here than my dragging code.
    It works but it is a little stiff
    compared to the fluid dragging
    of Hardwired´s code

    public void mousePressed(MouseEvent evt) {
    dragging = false;
    prevX = evt.getX(); // Current position of Mouse.
    prevY = evt.getY();
    }



    public void mouseDragged(MouseEvent evt) {
    if (prevX>frameMovX && prevX<(frameMovX+framew) && prevY>frameMovY
    && prevY<(frameMovY+frameh) && framelock) {
    dragging = true; // true when dragging occurs
    }
    }

    public void mouseReleased(MouseEvent evt) {

    if (dragging) {

    frameMovX = evt.getX() - prevX + frameMovX; // dragging stopped position of Mouse.
    frameMovY = evt.getY() - prevY + frameMovY; // calculating the new position from
    repaint(); // starting from the centre position
    dragging = false; // waiting for new drag
    }
    }

    public void mouseMoved(MouseEvent evt) {}
    public void mouseClicked(MouseEvent evt) {}
    public void mouseEntered(MouseEvent evt) {}
    public void mouseExited(MouseEvent evt) {}



    public void drawframe(Graphics g) {
    g.setColor(Color.RED);
    if (!framelock) {
    frameMovX = framex;
    frameMovY = framey;
    }

    g.drawRect(frameMovX, frameMovY, framew, frameh);
    g.drawRect(frameMovX-1, frameMovY-1, framew, frameh);
    g.drawRect(frameMovX-2, frameMovY-2, framew, frameh);
    }



    protected void paintComponent(Graphics g) {
    // This next line will fill component background
    // with background color specified in constructor
    // above.
    super.paintComponent(g);

    int x = getWidth();
    int y = getHeight();

    int xpic = (x - newwidth)/2;
    int ypic = (y - newheight)/2;

    //infotextPanel.setText(x + " / " + y);
    if(image != null) {
    g.drawImage(pic, xpic, ypic, this);
    }
    drawframe(g);
    }



    public void drawinfotext (String infotext, String txtcolor, String txtsize,
    int infotextx, int infotexty, int rw, int cl) {
    //infotextPanel.setSize(300,300);
    //setLocation(infotextx,infotexty);
    int offset = lineLength(infotext);
    settextColor(txtcolor);
    settextSize(txtsize);
    infotextx = infotextx + framex + (framew/2) - offset;
    infotexty = infotexty + framey + frameh - 20;
    infotextPanel.setBounds(infotextx,infotexty, framew ,frameh);
    infotextPanel.setText(infotext);
    }


    public int lineLength(String str) { // this will centre the info text
    int result=0;
    double sc = 7.4;
    if (!str.contains("\n"))
    result = str.length()/2;
    else
    result = str.indexOf("\n")/2;
    return (int) (result*sc);
    }


    public void displayImage(double sc) {
    this.setBackground(Color.WHITE);
    if (sc == 0) sc = 1.0;

    newwidth = (int)(imgwidth*sc);
    newheight = (int)(imgheight*sc);

    pic = image.getScaledInstance(newwidth, newheight, Image.SCALE_SMOOTH);

    revalidate();
    repaint();
    }

  10. #10
    willemjav is online now Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,019
    Rep Power
    8

    Default next step dragging a text component

    adding this code will keep the frame inside the JPanel

    public void drawframe(Graphics g) {
    g.setColor(Color.RED);
    if (!framelock) { // frame lock
    frameMovX = framex;
    frameMovY = framey;
    }
    if (frameMovX<0) // frame stays inside the borders
    frameMovX=0;
    if (frameMovY<0)
    frameMovY=0;
    if (frameMovX>(imagepanelX-framew))
    frameMovX=imagepanelX-framew;
    if (frameMovY>(imagepanelY-frameh))
    frameMovY=imagepanelY-frameh;

    The next step is to drag a component (JTextArea, which displays some info text lines over the image). I´d like to find the write position of the text over the image. The component is added to JPanel where the frame dragging takes place.
    1) I needed to add extra mouse listeners on the JTextArea.
    2) I need to know when the JTextArea is selected for dragging (by yet another listeners or by position coordinates that mark the contours of the component e.g. int height = infotextPanel.getSize().height etc. similar to the frame dragging of before.
    3) The position change can be done by infotextPanel.setBounds(infotextx,infotexty, w , h); infotextx set by the drag.
    For the moment I do not know how to handle 2). Once I have the mouse noticed over the JTextArea dragging can start (the setOpaque() is set to false.

    willemjav

  11. #11
    willemjav is online now Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,019
    Rep Power
    8

    Default

    write position = right position (sorry)

  12. #12
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    You can call setBounds on your textArea after dragging the frame rectangle, possibly in the mouseReleased method or in the ActionListener of a button.
    Here's another approach using graphics that can allow more flexibility and greater accuracy.
    Java Code:
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.font.*;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.text.*;
    import javax.imageio.ImageIO;
    import javax.swing.*;
    import javax.swing.event.*;
    
    public class ImageEditor extends JPanel implements ActionListener {
        Framer framer = new Framer(this);
        JTextField editor;
        String text;
        int size = 24;
        BufferedImage source;
        BufferedImage scaled;
        Rectangle rect = new Rectangle();
        boolean showFrame = true;
        double scale = 1.0;
    
        public ImageEditor(BufferedImage image) {
            source = image;
            scaleImage();
        }
    
        public void actionPerformed(ActionEvent e) {
            String ac = e.getActionCommand();
            if(ac.equals("SAVE")) {
                save();
            } else {
                if(ac.equals("SHOW FRAME"))
                    showFrame = ((JCheckBox)e.getSource()).isSelected();
                if(ac.equals("SET TEXT")) {
                    text = editor.getText();
                }
                repaint();
            }
        }
    
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D)g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
                                RenderingHints.VALUE_STROKE_PURE);
            int w = getWidth();
            int h = getHeight();
            int x = (w - scaled.getWidth())/2;
            int y = (h - scaled.getHeight())/2;
            g2.drawImage(scaled, x, y, this);
            g2.setPaint(Color.red);
            if(showFrame) {
                g2.draw(rect);
            }
            if(!framer.isDragging()) {
                drawText(g2);
            }
        }
    
        public Dimension getPreferredSize() {
            return new Dimension(500,500);
        }
    
        private void drawText(Graphics2D g2) {
            if(text == null || text.length() < 1)
                return;
            int pad = 10;
            int wrappingWidth = rect.width - 2*pad;
            FontRenderContext frc = g2.getFontRenderContext();
            AttributedString as = new AttributedString(text);
            as.addAttribute(TextAttribute.SIZE, Integer.valueOf(size));
            AttributedCharacterIterator aci = as.getIterator();
            LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
            float x = rect.x + pad;
            float y = rect.y + pad;
            while(lbm.getPosition() < text.length()) {
                TextLayout layout = lbm.nextLayout(wrappingWidth);
                //layout = layout.getJustifiedLayout(wrappingWidth);
                y += layout.getAscent();
                layout.draw(g2, x, y);
                y += layout.getDescent() + layout.getLeading();
            }
        }
    
        public void setFrame(Point p1, Point p2) {
            rect.setFrameFromDiagonal(p1, p2);
            repaint();
        }
    
        private void save() {
            int w = getWidth();
            int h = getHeight();
            int iw = scaled.getWidth();
            int ih = scaled.getHeight();
            int x = (w - iw)/2;
            int y = (h - ih)/2;
            int type = BufferedImage.TYPE_INT_RGB;
            BufferedImage toSave = new BufferedImage(iw, ih, type);
            Graphics2D g2 = toSave.createGraphics();
            g2.translate(-x, -y);
            paint(g2);
            g2.dispose();
            String ext = "jpg";
            String path = "imageEditor." + ext;
            try {
                ImageIO.write(toSave, ext, new File(path));
            } catch(IOException e) {
                System.out.println("write error: " + e.getMessage());
            }
            ImageIcon icon = new ImageIcon(toSave);
            JOptionPane.showMessageDialog(null, icon, "", -1);
        }
    
        private void scaleImage() {
            int w = (int)(scale*source.getWidth());
            int h = (int)(scale*source.getHeight());
            int type = BufferedImage.TYPE_INT_RGB;
            scaled = new BufferedImage(w, h, type);
            Graphics2D g2 = scaled.createGraphics();
            g2.drawImage(source, 0, 0, w, h, this);
            g2.dispose();
        }
    
        private JPanel getEditorPanel() {
            JPanel panel = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.weightx = 1.0;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            panel.add(getEditor(), gbc);
            panel.add(getControls(), gbc);
            return panel;
        }
    
        private JTextField getEditor() {
            editor = new JTextField();
            return editor;
        }
    
        private JPanel getControls() {
            final SpinnerNumberModel model =
                new SpinnerNumberModel(size,16,48,1);
            JSpinner spinner = new JSpinner(model);
            model.addChangeListener(new ChangeListener() {
                public void stateChanged(ChangeEvent e) {
                    size = model.getNumber().intValue();
                    repaint();
                }
            });
            String[] ids = { "show frame", "set text", "save" };
            JPanel panel = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.insets = new Insets(2,2,2,2);
            gbc.weightx = 1.0;
            for(int i = 0; i < ids.length; i++) {
                AbstractButton button = (i == 0)
                    ? new JCheckBox(ids[i], showFrame)
                    : new JButton(ids[i]);
                button.setActionCommand(ids[i].toUpperCase());
                button.addActionListener(this);
                if(i == 2) {
                    gbc.anchor = GridBagConstraints.EAST;
                    panel.add(new JLabel("font size"), gbc);
                    gbc.anchor = GridBagConstraints.WEST;
                    panel.add(spinner, gbc);
                    gbc.anchor = GridBagConstraints.CENTER;
                }
                panel.add(button, gbc);
            }
            return panel;
        }
    
        public static void main(String[] args) throws IOException {
            String path = "images/bison.jpg";
            BufferedImage image = ImageIO.read(new File(path));
            ImageEditor test = new ImageEditor(image);
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(test);
            f.add(test.getEditorPanel(), "Last");
            f.pack();
            f.setLocation(200,200);
            f.setVisible(true);
        }
    }
    
    class Framer extends MouseInputAdapter {
        ImageEditor editor;
        Point start;
        boolean dragging = false;
    
        public Framer(ImageEditor ie) {
            editor = ie;
            editor.addMouseListener(this);
            editor.addMouseMotionListener(this);
        }
    
        public void mousePressed(MouseEvent e) {
            start = e.getPoint();
            dragging = true;
        }
    
        public void mouseReleased(MouseEvent e) {
            dragging = false;
        }
    
        public void mouseDragged(MouseEvent e) {
            if(dragging) {
                editor.setFrame(start, e.getPoint());
            }
        }
    
        public boolean isDragging() { return dragging; }
    }

  13. #13
    willemjav is online now Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,019
    Rep Power
    8

    Default thick as a brick

    Hardwired, I taught I was almost there, I just needed a small detail more to get my component dragging…. but what I got instead is this enormous thick brick falling over me……. I started studying your code…. you do not even use a JTextArea … it is overwhelming.....
    The frame and the image draw are done in a graphical context, why not the text display as well…. that makes since. The problem is that graphical programming is more difficult and some times way over my head.

    The frame dragging was relatively easy to do and the text component dragging, which happens independently from the frame dragging, should be not very different, I taught. Let me explain what goes on in my head. There are three states:
    1) mouse clicked, get: start-position;
    2) mouse dragged, set: Boolean drag true;
    3) mouse released, get: end-position;
    So the new position = componentposition + endposition – startpostion.
    And the setBounds() is ideal to redirect the component.

    But there is actually a difference when dragging the frame compared to a component. The frame gets drawn into the JPanel and the motion listener is registered on the panel. A component is added to the panel and forms a “second layer”, when moving the mouse over the component it stops informing (so you have to register the component as well!).

    I have the JTextArea-dragging going, but the silly thing is that I have the component moving by dragging any where on the Jpanel (of course the independent frame dragging gets blocked by a logical or, because I can´t have both moving around that would be pretty messy).

    But I´d like the component only to move when the drag starts by clicking on the component itself (there should be a "simple" if-statement like, if JTextArea is selected, included at point 2). Text components do have a bunch of listeners but they deal with text manipulation and other things. The suitable EventListener does not work with JTextArea (I´d look into the addContainerListener).

    willemjav

  14. #14
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    Sorry for the thick brick.
    When you try to drag something like a text component in its parent container you run into trouble. One of the difficulties is that it consumes (uses) MouseEvents. Another is that mouseListeners added to the component have an awkward time trying to move the component in its parent. One way around this is to use a glassPane. Fortunately, there is an example of this in the tutorial (url shown in code comment below).
    The middle button is a JToggleButton used to allow dragging of the textArea. The other two are JButtons.
    Java Code:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.MouseInputAdapter;
    
    public class DragTest extends JPanel implements ActionListener {
        Rectangle rect = new Rectangle();
        JTextArea textArea = new JTextArea();
        GlassPane glassPane = new GlassPane(this);
    
        public DragTest() {
            glassPane.setVisible(false);
            setLayout(null);
            textArea.setOpaque(false);
            textArea.setLineWrap(true);
            textArea.setWrapStyleWord(true);
        }
    
        public void actionPerformed(ActionEvent e) {
            String ac = e.getActionCommand();
            if(ac.equals("ADD TEXTAREA")) {
                if(getComponentCount() == 0) {
                    add(textArea);
                }
                textArea.setBounds(rect);
                textArea.requestFocusInWindow();
                repaint();
            }
            if(ac.equals("DRAG TEXTAREA")) {
                boolean selected = ((AbstractButton)e.getSource()).isSelected();
                glassPane.setVisible(selected);
                if(selected) {
                    textArea.setEditable(false);
                    textArea.setFocusable(false);
                    textArea.setBorder(BorderFactory.createLineBorder(Color.blue));
                } else {
                    textArea.setEditable(true);
                    textArea.setFocusable(true);
                    textArea.setBorder(BorderFactory.createEmptyBorder(1,1,1,1));
                }
            }
            if(ac.equals("REMOVE TEXTAREA")) {
                if(getComponentCount() > 0) {
                    remove(textArea);
                    repaint();
                }
            }
        }
    
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D)g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setPaint(Color.red);
            g2.draw(rect);
        }
    
        private JPanel getControls() {
            String[] ids = { "add textArea", "drag textArea", "remove textArea" };
            JPanel panel = new JPanel();
            for(int i = 0; i < ids.length; i++) {
                AbstractButton button;
                if(i == 1)
                    button = new JToggleButton(ids[i], false);
                else
                    button = new JButton(ids[i]);
                button.setActionCommand(ids[i].toUpperCase());
                button.addActionListener(this);
                panel.add(button);
            }
            return panel;
        }
    
        public static void main(String[] args) {
            DragTest test = new DragTest();
            test.addMouseListener(test.mia);
            test.addMouseMotionListener(test.mia);
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setGlassPane(test.glassPane);
            f.add(test);
            f.add(test.getControls(), "Last");
            f.setSize(400,400);
            f.setLocation(200,200);
            f.setVisible(true);
        }
    
        private MouseInputAdapter mia = new MouseInputAdapter() {
            Point start;
            boolean dragging = false;
    
            public void mousePressed(MouseEvent e) {
                start = e.getPoint();
                dragging = true;
            }
    
            public void mouseReleased(MouseEvent e) {
                dragging = false;
            }
    
            public void mouseDragged(MouseEvent e) {
                if(dragging) {
                    rect.setFrameFromDiagonal(start, e.getPoint());
                    repaint();
                }
            }
        };
    }
    
    class GlassPane extends JComponent {
        DragTest component;
        JTextArea textArea;
    
        public GlassPane(DragTest dt) {
            component = dt;
            textArea = component.textArea;
            addMouseListener(mia);
            addMouseMotionListener(mia);
        }
    
        private MouseInputAdapter mia = new MouseInputAdapter() {
            Point offset = new Point();
            boolean dragging = false;
    
            public void mousePressed(MouseEvent e) {
                Point p = e.getPoint();
                if(!textArea.isEditable()) {
                    Rectangle r = textArea.getBounds();
                    if(r.contains(p)) {
                        // Mouse is over textArea.
                        offset.x = p.x - r.x;
                        offset.y = p.y - r.y;
                        dragging = true;
                    } else {
                        // Mouse may be over gui button area.
                        forwardEvent(e);
                    }
                }
            }
    
            /**
             * Code adapted from GlassPaneDemo.java found at
             * http://java.sun.com/docs/books/tutorial/
             *             uiswing/components/rootpane.html
             */
            private void forwardEvent(MouseEvent e) {
                Container topLevel = getTopLevelAncestor();
                Container contentPane = ((JFrame)topLevel).getContentPane();
                Point p = e.getPoint();
                p = SwingUtilities.convertPoint(e.getComponent(), p, contentPane);
                Component comp =
                    SwingUtilities.getDeepestComponentAt(contentPane, p.x, p.y);
                if(comp != null && comp instanceof AbstractButton) {
                    Point loc =
                        SwingUtilities.convertPoint(GlassPane.this, p, comp);
                    comp.dispatchEvent(new MouseEvent(comp,
                                                      e.getID(),
                                                      e.getWhen(),
                                                      e.getModifiers(),
                                                      loc.x,
                                                      loc.y,
                                                      e.getClickCount(),
                                                      e.isPopupTrigger()));
                }
            }
    
            public void mouseReleased(MouseEvent e) {
                dragging = false;
                forwardEvent(e);
            }
    
            public void mouseDragged(MouseEvent e) {
                if(dragging) {
                    int x = e.getX() - offset.x;
                    int y = e.getY() - offset.y;
                    textArea.setLocation(x,y);
                    // textArea is non-opaque so parent draws it.
                    component.repaint();
                }
            }
        };
    }

  15. #15
    willemjav is online now Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,019
    Rep Power
    8

    Default

    Keep on sculpting your tick bricks because I’ll read and study them all. As a beginning (java) programmer I am delighted with the swing (black) boxes. This kind of “module-programming” is relatively easy. The trouble starts, using these handy components, when some features are not present, such as dragging a text components (which makes since because they are not for dragging at the first place). A professional programmer should look for a good alternative but an amateur programmer (like me) tries to find some (dirty) tricks to make it work anyway.

    I did read before about glass panes, but I did not understand what to do with them. Your hint is interesting and I pulled your code through the compiler but can get the text to appear yet….. okay I might need some more time.
    In general: I should draw a glass over all the JPanel and do the mouse dragging on its transparent surface? Interesting idea (I was thinking of removing and adding the text comp… but that would be absurd…). I´ll need some more time and I´ll come back to the subject.

    willemjav

  16. #16
    willemjav is online now Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,019
    Rep Power
    8

    Default computer are sophisticated type-writers

    Returning to the Glasspane I have a hard time in understanding Hardwired´s code. I need to do some more studying. I do believe that I have gained a basic understanding of Java. But this Glasspane code is to complicated for me, is there any good text book for advanced reading that you could recommend, hardwired?

    Let me explain what I understood so far of the Glasspane concept.
    A Glasspane is not a swing component (there is no JGlasspane), it is actually a feature of some swing components. So one creates a class called e.g. MyGlasspane which extends JComponent (or some other component, see the api under setGlassPane()). One could do for instance the mouse-drag listening in that class. Once an object is created of that class (called mgp) one should say that, that object is going to function as a glasspane (I my case the object forms an transparent layer over the image edit panel where I would like to drag a JTextArea).

    When saying something like setGlassPane(mgp) (telling java to tread the object mgp as a glasspane). The problem is that the top container is a JPanel and JPanels do not like glasspanes (there is probably some profound reason that lays in inherence or whatever).
    So I changed the top container into a JFrame and found out that JFrames do not like paintComponent´s stuff.

    So here my labyrinth, hardwired?
    You see my point why I think computer are sophisticated type-writers because they can´t really figure out what I want!

    willemjav










    PHP Code:
    package setimages;
    
    
    /**
     *
     * 
     */
    /*
     * Main.java
     *
     * Created on March 2, 2008, 8:10 PM
     * The first class of setimages, called Loadimagesource
     * looks for the folder Imagestore that contains the photos
     * and the text file Slidessource.txt that sets the applet
     * parameters (in case there is no such folder the class creates one.
     * The second class, SetimagePanel, installs all the GUI controllers
     * for manipulating the images preparing them for the slideshow applet
     * The third class Editimages displays the image and the info text
     * here the actual photo editing takes place.
     * There will be an other class that simulates the applet slideshow
     * to see the result of the edit.
     +
     */
    
    
    
    import java.awt.*;
    import java.awt.Image;
    import java.awt.event.*;
    import java.util.Scanner;
    import javax.imageio.ImageIO;
    import javax.swing.*;
    import java.net.URL;
    import java.io.*;
    import java.awt.image.BufferedImage;
    import java.net.MalformedURLException;
    
       
        
        public class Editimages extends JPanel implements 
                MouseListener, MouseMotionListener {
             
            private JFileChooser fileDialog;
            private BufferedImage image;
            private Image pic;
            private int imgwidth, imgheight, newwidth, newheight, frameh,
                    framew, framex, framey, prevX, prevY, frdragX, frdragY, 
                    txtdragX, txtdragY, imagepanelX, imagepanelY,
                    infotextX, infotextY;
            private Scanner scanner;
            private Component infoPane;
            private JScrollPane scrollpane;
            private JTextArea infotextPanel;
            private File filepath;
            private String infotext;
            private Font smallFont, normalFont, largeFont, 
                    verylargeFont, currentFont;
            private boolean framedrag, infotextdrag, framelock, textinfolock;
            static private GlassPanel glasspanel;
            
            
            
         public Editimages(int framew, int frameh)   {
            
            
            imagepanelX = 800;
            imagepanelY = 480;
            setPreferredSize(new Dimension(imagepanelX, imagepanelY));
            this.framew = framew;
            this.frameh = frameh;
            framex = imagepanelX/2 - (framew/2);
            framey = imagepanelY/2 - (frameh/2);
            frdragX = framex;
            frdragY = framey;
            infotextPanel = new JTextArea();
            infotextPanel.setEditable(false);
            infotextPanel.setLineWrap(false);
            infotextPanel.setOpaque(false);
            setLayout(null);
            add(infotextPanel);
            addMouseListener(this);
            addMouseMotionListener(this);
           
            smallFont = new Font("SansSerif", Font.PLAIN, 10);
            normalFont = new Font("SansSerif", Font.PLAIN, 12);
            largeFont = new Font("SansSerif", Font.PLAIN, 14);
            verylargeFont = new Font("SansSerif", Font.PLAIN, 16);
         }
         
         
         
       class GlassPanel extends Component implements MouseListener, 
               MouseMotionListener   {
           
         public void mousePressed(MouseEvent evt) {
            framedrag = false;
            prevX = evt.getX(); // Current position of Mouse.
            prevY = evt.getY();
           // infotextPanel.setText(prevX + " " + prevY);
       }
       
       
       
       public void mouseDragged(MouseEvent evt) {
           if (prevX>frdragX && prevX<(frdragX+framew) && prevY>frdragY 
                   && prevY<(frdragY+frameh) && framelock)   {
                       framedrag = true;                         // true when dragging occurs 
           }
           if (prevX>frdragX && prevX<(frdragX+framew) && prevY>frdragY 
                   && prevY<(frdragY+frameh) && textinfolock)   {
                       infotextdrag = true;                         // true when dragging occurs 
           }
       }
       
       public void mouseReleased(MouseEvent evt) {
           
           if (framedrag)  {
               
             frdragX = evt.getX() - prevX + frdragX; // dragging stopped position of Mouse.
             frdragY = evt.getY() - prevY + frdragY; // calculating the new position from 
             repaint();                                  // starting from the centre position
             framedrag = false;                           // waiting for new drag  
             
           }
           
           if (infotextdrag)  {
             txtdragX = evt.getX() - prevX + txtdragX; // dragging stopped position of Mouse.
             txtdragY = evt.getY() - prevY + txtdragY; // calculating the new position from 
             drawinfotext ();
             repaint();
             infotextdrag = false;                           // waiting for new drag  
           }
       }
       
       public void mouseMoved(MouseEvent evt) {}
       public void mouseClicked(MouseEvent evt) {}
       public void mouseEntered(MouseEvent evt) {}
       public void mouseExited(MouseEvent evt) {}
        
       
       
       public void drawframe(Graphics g)  {
                g.setColor(Color.RED);           
                if (!framelock)  {              // frame lock
                    frdragX = framex;
                    frdragY = framey;
                    }
                if (frdragX<0)                // frame stays inside the borders   
                    frdragX=0;
                if (frdragY<0)    
                    frdragY=0;
                if (frdragX>(imagepanelX-framew))    
                    frdragX=imagepanelX-framew;
                if (frdragY>(imagepanelY-frameh))    
                    frdragY=imagepanelY-frameh;
                
                g.drawRect(frdragX, frdragY, framew,  frameh);
                g.drawRect(frdragX-1, frdragY-1, framew,  frameh);
                g.drawRect(frdragX-2, frdragY-2, framew,  frameh);
              //  infotextPanel.setText(frameMovX + " " + frameMovY);
           }  
           
           
       }
         
       public int getFramex() {
           return framex;
       } 
       
       public int getFramey() {
           return framey;
       } 
         
       private void setTextinfoposition(String path) {
           int height = infotextPanel.getSize().height;
           int width = infotextPanel.getSize().width;
           
       }
       
       public void frameUnlocked(boolean unl) {
           if (unl)  {
               framelock = true;
            //   infotextPanel.MouseListener(this);
             //  infotextPanel.MouseMotionListener(this);
              // infotextPanel.removeMouseListener(this);
              // infotextPanel.removeMouseMotionListener(this);
              // addMouseListener(this);
              // addMouseMotionListener(this);
           }
           else   {
               framelock = false;
           }
       }
       
       public void textinfoUnlocked(boolean unl) {
           if (unl)   {
               textinfolock = true;
              
           }    
           else   {
               textinfolock = false;
           }    
       }
       
      
       
       public void mousePressed(MouseEvent evt) {
            framedrag = false;
            prevX = evt.getX(); // Current position of Mouse.
            prevY = evt.getY();
       }
       
       
       
       public void mouseDragged(MouseEvent evt) {
           if (prevX>frdragX && prevX<(frdragX+framew) && prevY>frdragY 
                   && prevY<(frdragY+frameh) && framelock)   {
                       framedrag = true;                         // true when dragging occurs 
           }
           if (prevX>frdragX && prevX<(frdragX+framew) && prevY>frdragY 
                   && prevY<(frdragY+frameh) && textinfolock)   {
                       infotextdrag = true;                         // true when dragging occurs 
           }
       }
       
       public void mouseReleased(MouseEvent evt) {
           
           if (framedrag)  {
               
             frdragX = evt.getX() - prevX + frdragX; // dragging stopped position of Mouse.
             frdragY = evt.getY() - prevY + frdragY; // calculating the new position from 
             repaint();                                  // starting from the centre position
             framedrag = false;                           // waiting for new drag  
             
           }
           
           if (infotextdrag)  {
             txtdragX = evt.getX() - prevX + txtdragX; // dragging stopped position of Mouse.
             txtdragY = evt.getY() - prevY + txtdragY; // calculating the new position from 
             drawinfotext ();
             repaint();
             infotextdrag = false;                           // waiting for new drag  
           }
       }
       
       public void mouseMoved(MouseEvent evt) {}
       public void mouseClicked(MouseEvent evt) {}
       public void mouseEntered(MouseEvent evt) {}
       public void mouseExited(MouseEvent evt) {}
        
       
       
       public void drawframe(Graphics g)  {
                g.setColor(Color.RED);           
                if (!framelock)  {              // frame lock
                    frdragX = framex;
                    frdragY = framey;
                    }
                if (frdragX<0)                // frame stays inside the borders   
                    frdragX=0;
                if (frdragY<0)    
                    frdragY=0;
                if (frdragX>(imagepanelX-framew))    
                    frdragX=imagepanelX-framew;
                if (frdragY>(imagepanelY-frameh))    
                    frdragY=imagepanelY-frameh;
                
                g.drawRect(frdragX, frdragY, framew,  frameh);
                g.drawRect(frdragX-1, frdragY-1, framew,  frameh);
                g.drawRect(frdragX-2, frdragY-2, framew,  frameh);
        }
       
       
    
        protected void paintComponent(Graphics g) {
                // This next line will fill component background
                // with background color specified in constructor
                // above.
                super.paintComponent(g);
                
                    int x = getWidth();
                    int y = getHeight();
                    
                    int xpic = (x - newwidth)/2;
                    int ypic = (y - newheight)/2;
                   
                if(image != null) {
                    g.drawImage(pic, xpic, ypic, this);
                }
                drawframe(g);
         }
            
           
            
            public void setinfotext (String infotxt, String txtcolor, String txtsize, 
                    int infotextx, int infotexty) {
                    int offset = lineLength(infotxt);
               infotext = infotxt;
               settextColor(txtcolor);
               settextSize(txtsize);
               infotextX = infotextx;
               infotextY = infotexty;
            }
            
            public void drawinfotext ()   {
                if (!textinfolock)  {              // frame lock
                    txtdragX = infotextX;
                    txtdragY = infotextY;
                    }
               infotextPanel.setBounds(txtdragX+framex, txtdragY+framey, 300 ,200);
               infotextPanel.setText(infotext);
            }
            
            public int getInfotextX()  {
                return txtdragX;   
            }
            
             public int getInfotextY()  {
                return txtdragY;   
            }
            
            
            public int lineLength(String str)  {   // to try to center the text info
             int result=0;
             double sc = 7.4;
             if (!str.contains("\n"))
             result = str.length()/2;
             else
             result = str.indexOf("\n")/2; 
             return (int) (result*sc);
             
            }
    
            
            public void displayImage(double sc) {
                this.setBackground(Color.WHITE);
                if (sc == 0) sc = 1.0;
                
                newwidth = (int)(imgwidth*sc);
                newheight = (int)(imgheight*sc);
                
                pic = image.getScaledInstance(newwidth, newheight, Image.SCALE_SMOOTH);
                
                revalidate();
                repaint();
            }
            
            
            
         public void downloadImage(String path) { 
            try {
               
                image = ImageIO.read(new File(path));
            } 
            catch (IOException ex) {
                System.out.println("can not read : " + path);
                System.out.println(ex.getMessage());
            }
            if(image != null) {
            imgwidth = image.getWidth();
            imgheight = image.getHeight();
            }
            else
               System.out.println("can not read size : " + path);  
        } 
            
            
        
        
       
         private void settextColor(String str) {   //private void settextColor(String str);
           
            if (str.equalsIgnoreCase("RED"))
               infotextPanel.setForeground(Color.RED);
            else
            if (str.equalsIgnoreCase("BLUE"))
                infotextPanel.setForeground(Color.BLUE);
            else
            if (str.equalsIgnoreCase("GREEN"))
                infotextPanel.setForeground(Color.GREEN);
            else
            if (str.equalsIgnoreCase("WHITE"))
                infotextPanel.setForeground(Color.WHITE);
            else
             if (str.equalsIgnoreCase("YELLOW"))
                infotextPanel.setForeground(Color.YELLOW);
            else
                infotextPanel.setForeground(Color.BLACK);
            
         }
         
         private void settextSize(String str) {   
             if (str.equalsIgnoreCase("small"))
                 infotextPanel.setFont(smallFont);
             else
             if (str.equalsIgnoreCase("large"))
                  infotextPanel.setFont(largeFont);
             else
             if (str.equalsIgnoreCase("verylarge"))
                  infotextPanel.setFont(verylargeFont);
             else
                  infotextPanel.setFont(normalFont);
             
         }
           
           
       
        
        public File Openfiledialogue() {  // not used for the moment
            if (fileDialog == null)   
            fileDialog = new JFileChooser();
            fileDialog.setDialogTitle("Load the Image you want to edit");
            fileDialog.setSelectedFile(null);                                // No file is initially selected.
            fileDialog.setFileSelectionMode(fileDialog.DIRECTORIES_ONLY);    // select only directories
            int option = fileDialog.showOpenDialog(this);
                // (Using "this" as a parameter to showOpenDialog() assumes that the
                //  readFile() method is an instance method in a GUI component class.)
            if (option == JFileChooser.APPROVE_OPTION)    // if dir is selected return File
                return fileDialog.getSelectedFile();              // if not return null, end program
            else 
                return null;
       
        }
    
       
    
        
    
     
    }
    [PHP][PHP][QUOTE]

  17. #17
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    is there any good text book for advanced reading that you could recommend, hardwired?
    The only place I have read to learn about this is How to Use Root Panes in the tutorial, esp. GlassPaneDemo.java, and JRootPane class api in the javadocs. The rest has been with trial and error.
    About your glassPane. You'll want to use a JComponent which is non-opaque. If you use a JPanel, which is opaque by default, call setOpaque(false) on it to make it transparent. You want to see through this top component to the image below.

  18. #18
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    Here is a simpler version of DragTest which uses an OverlayLayout instead of a glassPane. It still has two layers: the bottom layer for your image and rectangle (frame) and the top layer for adding/editing/moving/removing the textArea.
    I discovered the OverlayLayout during a search of the Sun java forums and later found out that it is useful for certain kinds of graphics work. I never tried to use it in place of a glassPane but it seems to work well (below). One major pain with using a glassPane is that it covers the entire JRootPane and InputEvents such as KeyEvents and MouseEvents must be redispatched to target components below.
    In this example app there is a non-opaque JComponent mounted over the JPanel which can/will show the image you want to edit. Its visibility is toggled, as with the glassPane, to enable access to the top layer or bottom layer as needed.
    The selection key is the state of the JToggleButton in the center of the south section. The buttons are left free and accessible to the user; no redispatching of MouseEvents.
    Java Code:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.MouseInputAdapter;
    
    public class DragOverlayTest extends JPanel implements ActionListener {
        Rectangle rect = new Rectangle();
        JTextArea textArea = new JTextArea();
        ClearPane clearPane = new ClearPane(this);
    
        public DragOverlayTest() {
            clearPane.setVisible(false);
            setLayout(null);
            textArea.setOpaque(false);
            textArea.setLineWrap(true);
            textArea.setWrapStyleWord(true);
        }
    
        public void actionPerformed(ActionEvent e) {
            String ac = e.getActionCommand();
            if(ac.equals("ADD TEXTAREA")) {
                if(getComponentCount() == 0) {
                    add(textArea);
                }
                textArea.setBounds(rect);
                textArea.requestFocusInWindow();
                repaint();
            }
            if(ac.equals("DRAG TEXTAREA")) {
                // The clearPane will be visible when the toggleButton
                // is selected and not visible when it is not selected.
                boolean selected = ((AbstractButton)e.getSource()).isSelected();
                clearPane.setVisible(selected);
                if(selected) {
                    // Make the textArea inert so it will not consume
                    // MouseEvents and set a border to show its bounds
                    // to make dragging operations easier.
                    textArea.setEditable(false);
                    textArea.setFocusable(false);
                    textArea.setBorder(BorderFactory.createLineBorder(Color.blue));
                } else {
                    // Make textArea ready for editing and invisible
                    // so it doesn't interfere with image editing.
                    textArea.setEditable(true);
                    textArea.setFocusable(true);
                    textArea.setBorder(BorderFactory.createEmptyBorder(1,1,1,1));
                }
            }
            if(ac.equals("REMOVE TEXTAREA")) {
                if(getComponentCount() > 0) {
                    remove(textArea);
                    repaint();
                }
            }
        }
    
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D)g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setPaint(Color.red);
            g2.draw(rect);
        }
    
        private JPanel getOverlayComponent() {
            JPanel panel = new JPanel();
            OverlayLayout overlay = new OverlayLayout(panel);
            panel.setLayout(overlay);
            panel.add(clearPane);
            panel.add(this);
            return panel;
        }
    
        private JPanel getControls() {
            String[] ids = { "add textArea", "drag textArea", "remove textArea" };
            JPanel panel = new JPanel();
            for(int i = 0; i < ids.length; i++) {
                AbstractButton button;
                if(i == 1)
                    button = new JToggleButton(ids[i], false);
                else
                    button = new JButton(ids[i]);
                button.setActionCommand(ids[i].toUpperCase());
                button.addActionListener(this);
                panel.add(button);
            }
            return panel;
        }
    
        public static void main(String[] args) {
            DragOverlayTest test = new DragOverlayTest();
            test.addMouseListener(test.mia);
            test.addMouseMotionListener(test.mia);
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(test.getOverlayComponent());
            f.add(test.getControls(), "Last");
            f.setSize(400,400);
            f.setLocation(200,200);
            f.setVisible(true);
        }
    
        private MouseInputAdapter mia = new MouseInputAdapter() {
            Point start;
            boolean dragging = false;
    
            public void mousePressed(MouseEvent e) {
                start = e.getPoint();
                dragging = true;
            }
    
            public void mouseReleased(MouseEvent e) {
                dragging = false;
            }
    
            public void mouseDragged(MouseEvent e) {
                if(dragging) {
                    rect.setFrameFromDiagonal(start, e.getPoint());
                    repaint();
                }
            }
        };
    }
    
    class ClearPane extends JComponent {
        DragOverlayTest component;
        JTextArea textArea;
    
        public ClearPane(DragOverlayTest dot) {
            component = dot;
            textArea = component.textArea;
            addMouseListener(mia);
            addMouseMotionListener(mia);
        }
    
        private MouseInputAdapter mia = new MouseInputAdapter() {
            Point offset = new Point();
            boolean dragging = false;
    
            public void mousePressed(MouseEvent e) {
                Point p = e.getPoint();
                if(!textArea.isEditable()) {
                    Rectangle r = textArea.getBounds();
                    if(r.contains(p)) {
                        // Mouse is over textArea.
                        // Prepare for dragging.
                        offset.x = p.x - r.x;
                        offset.y = p.y - r.y;
                        dragging = true;
                    }
                }
            }
    
            public void mouseReleased(MouseEvent e) {
                dragging = false;
            }
    
            public void mouseDragged(MouseEvent e) {
                if(dragging) {
                    int x = e.getX() - offset.x;
                    int y = e.getY() - offset.y;
                    textArea.setLocation(x,y);
                    // textArea is non-opaque so parent draws it.
                    component.repaint();
                }
            }
        };
    }

  19. #19
    willemjav is online now Senior Member
    Join Date
    Dec 2007
    Location
    Spain
    Posts
    1,019
    Rep Power
    8

    Default

    Thanks for the new code (I taught about the concept used in that code as well but had no idea how to realize it).
    My question above
    "is there any good text book for advanced reading that you could recommend, hardwired?"
    was not mend only concerning the glass pane. I´d like to conduct further study of advanced java concepts. Is there any good text-book you can recommend?
    I still like to figure out how the glass pane code works by writing my own one. But for the moment I am also transforming a 20 year old pascal code into java (see java lobby)

    willemjav

  20. #20
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    is there any good text book for advanced reading that you could recommend
    No; most of what I've learned came from the Sun tutorial and articles linked in/from it.

Similar Threads

  1. scaling images
    By willemjav in forum Java Applets
    Replies: 7
    Last Post: 06-19-2008, 09:54 AM
  2. The mouse and the cheese
    By Don Quixote in forum Java 2D
    Replies: 4
    Last Post: 08-15-2007, 10:55 PM
  3. mouse over on JButton
    By gradon in forum Java Applets
    Replies: 1
    Last Post: 08-04-2007, 05:50 AM
  4. Use the mouse position
    By susan in forum Java Applets
    Replies: 1
    Last Post: 07-28-2007, 11:10 PM
  5. Mouse over JButton
    By sandor in forum AWT / Swing
    Replies: 1
    Last Post: 05-17-2007, 09:15 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •