简体   繁体   中英

JSpinner's JButton to ImageIcon

Trying to replace the JButton controller of a JSpinner to ImageIcon instead. But for some reason it does not listen to any mouseclicks(installButtonListeners() in BasicSpinnerUI seems to add MouseListener ). Any ideas why and how to fix?

public class SpinnerIconBtn extends JFrame {

    public SpinnerIconBtn(){
        JSpinner spinner = new JSpinner();
        spinner.setUI(new JSpinnerArrow());

        this.add(spinner);
        this.pack();
        this.setVisible(true);
    }

    class JSpinnerArrow extends BasicSpinnerUI {

        @Override
        protected Component createNextButton() {
            Component c = createArrowButton(SwingConstants.NORTH);
            c.setName("Spinner.nextButton");
            installNextButtonListeners(c);
            return c;
        }

        @Override
        protected Component createPreviousButton() {
            Component c = createArrowButton(SwingConstants.SOUTH);
            c.setName("Spinner.previousButton");
            installPreviousButtonListeners(c);
            return c;
        }

        private Component createArrowButton(int direction) {
            String path = "/Users/tst.png";
            JLabel icon = new JLabel(new ImageIcon(path));
            return icon;
        }
    }

    public static void main(String[] args) {
        new SpinnerIconBtn();
    }
}
  • do not to change Icon, use paintIcon()

  • change LayoutManager if ArrowsButtons are moved of Icons are too big

.

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

class Testing {
    //int counter = 0;//proper setting

    int counter = 7195;//testing hours 'tick over' correctly
    JSpinner spinner = new JSpinner();
    JTextField editor = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField();
    java.text.DecimalFormat df = new java.text.DecimalFormat("00");

    public void buildGUI() {
        spinner.setUI(new EndlessHoursUI());
        JFrame f = new JFrame();
        f.getContentPane().add(spinner);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }

    class EndlessHoursUI extends javax.swing.plaf.basic.BasicSpinnerUI {

        public EndlessHoursUI() {
            setTime();
        }

        @Override
        protected void installNextButtonListeners(Component c) {
        }// do nothing

        @Override
        protected void installPreviousButtonListeners(Component c) {
        }// do nothing

        @Override
        protected Component createNextButton() {
            JButton btnNext = (JButton) super.createNextButton();
            btnNext.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent ae) {
                    changeSpinner(1);
                }
            });
            return btnNext;
        }

        @Override
        protected Component createPreviousButton() {
            JButton btnPrevious = (JButton) super.createPreviousButton();
            btnPrevious.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent ae) {
                    changeSpinner(-1);
                }
            });
            return btnPrevious;
        }
    }

    public void changeSpinner(int amount) {
        if (counter > 0 || amount > 0) {
            counter += amount;
            setTime();
        }
    }

    public void setTime() {
        int hours = counter / 3600;
        int mins = (counter / 60) % 60;
        int secs = counter % 60;
        String time = df.format(hours) + ":" + df.format(mins) + ":" + df.format(secs);
        editor.setText(time);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Testing().buildGUI();
            }
        });
    }
}

Did not manage to solve it with the answers. Tweaked the buttons by removing all without the arrows and then I moved the arrows together:

private Component createArrowButton(int direction) {

        JButton b = new BasicArrowButton(direction){

            private static final long serialVersionUID = 1L;

            @Override
            public void paintTriangle(Graphics g, int x, int y, int size,
                    int direction, boolean isEnabled) {


                if(direction == NORTH){
                    y +=3;
                }
                else if(direction == SOUTH){
                    y -=3;
                }

                Color shadow = UIManager.getColor("controlShadow");                 
                Color darkShadow = UIManager.getColor("controlDkShadow");
                Color highlight = UIManager.getColor("controlLtHighlight");

                Color oldColor = g.getColor();
                int mid, i, j;

                j = 0;
                size = Math.max(size, 2);
                mid = (size / 2) - 1;

                g.translate(x, y);
                if (isEnabled)
                    g.setColor(darkShadow);
                else
                    g.setColor(shadow);

                switch (direction) {
                case NORTH:

                    for (i = 0; i < size; i++) {
                        g.drawLine(mid - i, i, mid + i, i);
                    }
                    if (!isEnabled) {
                        g.setColor(highlight);
                        g.drawLine(mid - i + 2, i, mid + i, i);
                    }
                    break;
                case SOUTH:
                    if (!isEnabled) {
                        g.translate(1, 1);
                        g.setColor(highlight);
                        for (i = size - 1; i >= 0; i--) {
                            g.drawLine(mid - i, j, mid + i, j);
                            j++;
                        }
                        g.translate(-1, -1);
                        g.setColor(shadow);
                    }

                    j = 0;
                    for (i = size - 1; i >= 0; i--) {
                        g.drawLine(mid - i, j, mid + i, j);
                        j++;
                    }
                    break;
                case WEST:
                    for (i = 0; i < size; i++) {
                        g.drawLine(i, mid - i, i, mid + i);
                    }
                    if (!isEnabled) {
                        g.setColor(highlight);
                        g.drawLine(i, mid - i + 2, i, mid + i);
                    }
                    break;
                case EAST:
                    if (!isEnabled) {
                        g.translate(1, 1);
                        g.setColor(highlight);
                        for (i = size - 1; i >= 0; i--) {
                            g.drawLine(j, mid - i, j, mid + i);
                            j++;
                        }
                        g.translate(-1, -1);
                        g.setColor(shadow);
                    }

                    j = 0;
                    for (i = size - 1; i >= 0; i--) {
                        g.drawLine(j, mid - i, j, mid + i);
                        j++;
                    }
                    break;
                }
                g.translate(-x, -y);
                g.setColor(oldColor);
            }
        };
        b.setBorder(BorderFactory.createEmptyBorder());
        //removes content area
        b.setContentAreaFilled(false);
        b.setInheritsPopupMenu(true);
        b.setOpaque(false);
        b.setBackground(color);

        return b;
    }

installNextButtonListeners() and installPreviousButtonListeners() call the following method:

private void installButtonListeners(Component c,
                                    ArrowButtonHandler handler) {
    if (c instanceof JButton) {
        ((JButton)c).addActionListener(handler);
    }
    c.addMouseListener(handler);
}

Cause of the instanceof check the ArrowButtonHandler won't get attached as an ActionListener to your JLabel , which handles the spinning.

You may use a subclass of JButton instead of the JLabel .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM