Java 带有图像、文本、箭头和菜单的按钮

Java 带有图像、文本、箭头和菜单的按钮,java,swing,Java,Swing,我想创建一个按钮,它有一个图标,上面有文本,角落有箭头。单击后,将显示一个菜单。除箭头部分外,我能够实现上述所有功能。我知道我可以将图标和箭头保存在一个png文件中的图像文件。但是,我不想更改图标文件。这是我到目前为止的代码 如何添加箭头(无论是通过编程方式还是从另一个箭头图像文件添加到按钮) 一个快速的方法是 Image img1=imageIcon1.getImage(); Image img2=imageIcon2.getImage(); Graphics g=img1.getGraphi

我想创建一个按钮,它有一个图标,上面有文本,角落有箭头。单击后,将显示一个菜单。除箭头部分外,我能够实现上述所有功能。我知道我可以将图标和箭头保存在一个png文件中的图像文件。但是,我不想更改图标文件。这是我到目前为止的代码

如何添加箭头(无论是通过编程方式还是从另一个箭头图像文件添加到按钮)


一个快速的方法是

Image img1=imageIcon1.getImage();
Image img2=imageIcon2.getImage();
Graphics g=img1.getGraphics();
g.drawImage(img2, x, y, sizex, sizey, null)
其中x,y是在第一个图标上放置第二个图标(箭头),sizex,sizey是第二个图标的缩小尺寸。你可以尝试改变这些

你必须有另一种方法

public JButtonMenu(ImageIcon imageIcon1, ImageIcon imageIcon2, String title, String []list) {
  // above segment here
  // continue with the rest of the code

}

这基本上是的一个淡化版本,但重点是需要绘制额外的图像,以及需要实现的一些其他功能,以确保原始文本和图标精确偏移

导入java.awt.AlphaComposite;
导入java.awt.Color;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.GridBagLayout;
导入java.awt.Image;
导入java.awt.Insets;
导入java.awt.Rectangle;
导入java.awt.Toolkit;
导入java.awt.image.buffereImage;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公开课考试{
公共静态void main(字符串[]args){
新测试();
}
公开考试(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
例如printStackTrace();
}
SplitButton btn=新的SplitButton();
btn.setText(“这是一个拆分按钮”);
JFrame=新JFrame(“测试”);
frame.setLayout(新的GridBagLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
帧添加(btn);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类SplitButton扩展了JButton{
专用整数分隔符间距=4;
私有int splitWidth=30;
私有int arrowSize=8;
私有矩形分割矩形;
专用颜色箭头颜色=Color.BLACK;
私有颜色禁用RowColor=Color.GRAY;
私有图像;
公共拆分按钮(){
超级();
}
@凌驾
公共插图getInsets(){
Insets Insets=(Insets)super.getInsets().clone();
insets.right+=拆分宽度;
返回插图;
}
@凌驾
公共插图-获取插图(插图-插图){
Insets insets1=getInsets();
insets.left=insets1.left;
insets.right=insets1.right;
insets.bottom=insets1.bottom;
insets.top=insets1.top;
返回插图1;
}
/**
*返回分隔符间距。分隔符间距是和上方的空间
*分隔符下方(将鼠标悬停在
*拆分按钮的一部分)。
*
*@return separatorspatingimage=null;//使用新的
*大小
*/
public int getseparatorspace(){
返回分隔符间隔;
}
/**
*设置分隔符间距。分隔符间距是上方和下方的空间
*分隔符(将鼠标悬停在分割上时绘制的线)
*按钮的一部分)。
*
*@param间距
*/
公共空隙集分隔间距(整数间距){
如果(间距!=分隔符间距和间距>=0){
int old=分隔符间距;
此。分隔符间距=间距;
image=null;
FireProperty更改(“分隔空间”,旧,分隔空间);
重新验证();
重新油漆();
}
}
/**
*获取箭头的颜色。
*
*@返回箭头颜色
*/
公共颜色getArrowColor(){
返回箭头颜色;
}
/**
*设置箭头颜色。
*
*@param颜色
*/
公共空间设置箭头颜色(颜色){
如果(箭头颜色!=颜色){
颜色旧=箭头颜色;
this.arrowColor=颜色;
image=null;
FireProperty更改(“箭头颜色”,旧,箭头颜色);
重新油漆();
}
}
/**
*获取禁用的箭头颜色
*
*@return禁用箭头的rowColor颜色(如果未连接弹出窗口)。
*/
公共颜色getDisabledArrowColor(){
返回禁用的颜色;
}
/**
*设置禁用的箭头颜色
*
*@param color箭头的颜色(如果未连接弹出窗口)。
*/
public void setDisabledArrowColor(颜色){
如果(禁用DarRowColor!=颜色){
旧颜色=禁用的颜色如箭头所示;
this.disabledArrowColor=颜色;
image=null;//使用新颜色重新绘制图像
FireProperty更改(“DisabledRowColor”,旧,DisabledRowColor);
}
}
/**
*Splitwidth是按钮分割部分的宽度。
*
*@return splitWidth
*/
public int getSplitWidth(){
返回拆分窗口
public JButtonMenu(ImageIcon imageIcon1, ImageIcon imageIcon2, String title, String []list) {
  // above segment here
  // continue with the rest of the code

}
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                SplitButton btn = new SplitButton();
                btn.setText("This is a split button");

                JFrame frame = new JFrame("Testing");
                frame.setLayout(new GridBagLayout());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(btn);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class SplitButton extends JButton {

        private int separatorSpacing = 4;
        private int splitWidth = 30;
        private int arrowSize = 8;

        private Rectangle splitRectangle;
        private Color arrowColor = Color.BLACK;
        private Color disabledArrowColor = Color.GRAY;
        private Image image;

        public SplitButton() {
            super();
        }

        @Override
        public Insets getInsets() {
            Insets insets = (Insets) super.getInsets().clone();
            insets.right += splitWidth;
            return insets;
        }

        @Override
        public Insets getInsets(Insets insets) {
            Insets insets1 = getInsets();
            insets.left = insets1.left;
            insets.right = insets1.right;
            insets.bottom = insets1.bottom;
            insets.top = insets1.top;
            return insets1;
        }

        /**
         * Returns the separatorSpacing. Separator spacing is the space above and
         * below the separator( the line drawn when you hover your mouse over the
         * split part of the button).
         *
         * @return separatorSpacingimage = null; //to repaint the image with the new
         * size
         */
        public int getSeparatorSpacing() {
            return separatorSpacing;
        }

        /**
         * Sets the separatorSpacing.Separator spacing is the space above and below
         * the separator( the line drawn when you hover your mouse over the split
         * part of the button).
         *
         * @param spacing
         */
        public void setSeparatorSpacing(int spacing) {
            if (spacing != separatorSpacing && spacing >= 0) {
                int old = separatorSpacing;
                this.separatorSpacing = spacing;
                image = null;
                firePropertyChange("separatorSpacing", old, separatorSpacing);
                revalidate();
                repaint();
            }
        }

        /**
         * Gets the color of the arrow.
         *
         * @return arrowColor
         */
        public Color getArrowColor() {
            return arrowColor;
        }

        /**
         * Set the arrow color.
         *
         * @param color
         */
        public void setArrowColor(Color color) {
            if (arrowColor != color) {
                Color old = arrowColor;
                this.arrowColor = color;
                image = null;
                firePropertyChange("arrowColor", old, arrowColor);
                repaint();
            }
        }

        /**
         * gets the disabled arrow color
         *
         * @return disabledArrowColor color of the arrow if no popup attached.
         */
        public Color getDisabledArrowColor() {
            return disabledArrowColor;
        }

        /**
         * sets the disabled arrow color
         *
         * @param color color of the arrow if no popup attached.
         */
        public void setDisabledArrowColor(Color color) {
            if (disabledArrowColor != color) {
                Color old = disabledArrowColor;
                this.disabledArrowColor = color;
                image = null; //to repaint the image with the new color
                firePropertyChange("disabledArrowColor", old, disabledArrowColor);
            }
        }

        /**
         * Splitwidth is the width of the split part of the button.
         *
         * @return splitWidth
         */
        public int getSplitWidth() {
            return splitWidth;
        }

        /**
         * Splitwidth is the width of the split part of the button.
         *
         * @param width
         */
        public void setSplitWidth(int width) {
            if (splitWidth != width) {
                int old = splitWidth;
                this.splitWidth = width;
                firePropertyChange("splitWidth", old, splitWidth);
                revalidate();
                repaint();
            }
        }

        /**
         * gets the size of the arrow.
         *
         * @return size of the arrow
         */
        public int getArrowSize() {
            return arrowSize;
        }

        /**
         * sets the size of the arrow
         *
         * @param size
         */
        public void setArrowSize(int size) {
            if (arrowSize != size) {
                int old = arrowSize;
                this.arrowSize = size;
                image = null; //to repaint the image with the new size
                firePropertyChange("setArrowSize", old, arrowSize);
                revalidate();
                repaint();
            }
        }

        /**
         * Gets the image to be drawn in the split part. If no is set, a new image
         * is created with the triangle.
         *
         * @return image
         */
        public Image getImage() {
            if (image == null) {
                Graphics2D g = null;
                BufferedImage img = new BufferedImage(arrowSize, arrowSize, BufferedImage.TYPE_INT_RGB);
                g = (Graphics2D) img.createGraphics();
                g.setColor(Color.WHITE);
                g.fillRect(0, 0, img.getWidth(), img.getHeight());
                g.setColor(isEnabled() ? arrowColor : disabledArrowColor);
                //this creates a triangle facing right >
                g.fillPolygon(new int[]{0, 0, arrowSize / 2}, new int[]{0, arrowSize, arrowSize / 2}, 3);
                g.dispose();
                //rotate it to face downwards
                img = rotate(img, 90);
                BufferedImage dimg = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
                g = (Graphics2D) dimg.createGraphics();
                g.setComposite(AlphaComposite.Src);
                g.drawImage(img, null, 0, 0);
                g.dispose();
                for (int i = 0; i < dimg.getHeight(); i++) {
                    for (int j = 0; j < dimg.getWidth(); j++) {
                        if (dimg.getRGB(j, i) == Color.WHITE.getRGB()) {
                            dimg.setRGB(j, i, 0x8F1C1C);
                        }
                    }
                }

                image = Toolkit.getDefaultToolkit().createImage(dimg.getSource());
            }
            return image;
        }

        /**
         *
         * @param g
         */
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            //Graphics gClone = g.create();//EDIT: Hervé Guillaume
            Color oldColor = g.getColor();
            splitRectangle = new Rectangle(getWidth() - splitWidth, 0, splitWidth, getHeight());
            g.translate(splitRectangle.x, splitRectangle.y);
            int mh = getHeight() / 2;
            int mw = splitWidth / 2;
            g.drawImage(getImage(), mw - arrowSize / 2, mh + 2 - arrowSize / 2, null);
            if (getModel().isRollover() || isFocusable()) {
                g.setColor(UIManager.getLookAndFeelDefaults().getColor("Button.background"));
                g.drawLine(1, separatorSpacing + 2, 1, getHeight() - separatorSpacing - 2);
                g.setColor(UIManager.getLookAndFeelDefaults().getColor("Button.shadow"));
                g.drawLine(2, separatorSpacing + 2, 2, getHeight() - separatorSpacing - 2);
            }
            g.setColor(oldColor);
            g.translate(-splitRectangle.x, -splitRectangle.y);
        }

        /**
         * Rotates the given image with the specified angle.
         *
         * @param img image to rotate
         * @param angle angle of rotation
         * @return rotated image
         */
        private BufferedImage rotate(BufferedImage img, int angle) {
            int w = img.getWidth();
            int h = img.getHeight();
            BufferedImage dimg = dimg = new BufferedImage(w, h, img.getType());
            Graphics2D g = dimg.createGraphics();
            g.rotate(Math.toRadians(angle), w / 2, h / 2);
            g.drawImage(img, null, 0, 0);
            return dimg;
        }

    }

}