Как можно обновить JButton с помощью ImageIcon?

1

Как гласит название, можно ли каким-либо образом перекрасить JButton кроме repaint(), validate() и invalidate()? Я использовал их, чтобы перекрасить свой JButton, но он все тот же. Вот мой код:

package buttonrepaint;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;


public class Buttonrepaint {

JFrame Card = new JFrame();
GridBagConstraints c = new GridBagConstraints();
Border etch = BorderFactory.createEtchedBorder(Color.white,Color.gray);

public static String buttonname;
public static String num1="";   public static String num2=""; public static String num3="";


public static int flagnum1=1, flagnum2=1, flagnum3=1;


JButton btn_1;  JButton btn_2;  JButton btn_3;


    static int buttonGroup=1;
int stat = 0;

   public static ArrayList<HashMap<String, String>> prodbutton = getProductsButton(buttonGroup);


public Buttonrepaint(){
        Card.setVisible(true);
    Card.setSize(522,500);
    Card.setTitle("Frequency Distribution");
    Card.setResizable(false);

    final Toolkit toolkit = Toolkit.getDefaultToolkit();
    Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();      
    int x=(int)((dimension.getWidth() - Card.getWidth())/4);
    int y=(int)((dimension.getHeight() - Card.getHeight())/2);

    Card.setLocation(x, y);
            Card.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

    FlowLayout flow_1 = new FlowLayout(FlowLayout.RIGHT,1,1);
    final JPanel panel_1 = new JPanel();
    panel_1.setBackground(Color.WHITE);
    panel_1.setBorder(new EmptyBorder(10, 10, 10, 10));
    panel_1.setLayout(flow_1);

    final JButton btnGroup3 = new JButton("Next");
    //btnGroup3.setIcon(new ImageIcon("more_buttons\\yellow.png"));
    //btnGroup3.setBorderPainted(false);  
           // btnGroup3.setFocusPainted(false);
           // btnGroup3.setContentAreaFilled(false); 
            btnGroup3.setHorizontalTextPosition(JButton.CENTER);
    btnGroup3.setFont(new Font("Calibri", Font.PLAIN, 18));
    btnGroup3.setPreferredSize(new Dimension(80, 80));
    btnGroup3.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            buttonGroup++;

            if(prodbutton==null)
            {
                btnGroup3.setText("Back");
                prodbutton.clear();
                stat=1;
                btn_1.invalidate();
            }
            else
            {
                System.out.println("EMPTY!!!!!");
                buttonGroup--;
                stat=0;
            }


        }
    });
    panel_1.add(btnGroup3);
    try{
        num1=Capitalize(prodbutton.get(0).get("prodname"));

        if(prodbutton.get(0).get("butstatus").equals("0"))
        {flagnum1=0;}
    }catch (Exception e) 
        {flagnum1=0;}       

    try{
        num2=Capitalize(prodbutton.get(1).get("prodname"));

        if(prodbutton.get(1).get("butstatus").equals("0"))
        {flagnum2=0;}
    }catch (Exception e) 
        {flagnum2=0;}   

    try{
        num3=Capitalize(prodbutton.get(2).get("prodname"));

        if(prodbutton.get(2).get("butstatus").equals("0"))
        {flagnum3=0;}
    }catch (Exception e) 
        {flagnum3=0;}   


    btn_1 = new JButton("<html><p align=center>"+num1+"</p></html>");
    //btn_1.setIcon(new ImageIcon("more_buttons\\lightblue.png"));
    //btn_1.setBorderPainted(false);  
            //btn_1.setFocusPainted(false);
            //btn_1.setContentAreaFilled(false); 
            btn_1.setHorizontalTextPosition(JButton.CENTER);
    btn_1.setFont(new Font("Calibri", Font.BOLD, 14));
    btn_1.setPreferredSize(new Dimension(80, 80));

    if(flagnum1==0)
    {   btn_1.setEnabled(false);    }
    btn_1.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            try{

                if(flagnum1==1)
                {
                    if(num1!=null)
                    {
                        buttonname = prodbutton.get(0).get("prodname");
                        //quantity_panel qp = new quantity_panel();
                    }

                }
                if (stat==1)
                {

                    buttonname=buttonname;

                    //quantity_panel qp = new quantity_panel();
                }


            }catch (Exception e) {System.out.println("Error~");}
        }
    });
    panel_1.add(btn_1);

    btn_2 = new JButton("<html><p align=center>"+num2+"</p></html>");
    //btn_2.setIcon(new ImageIcon("more_buttons\\lightblue.png"));
    //btn_2.setBorderPainted(false);  
           // btn_2.setFocusPainted(false);
           // btn_2.setContentAreaFilled(false); 
            btn_2.setHorizontalTextPosition(JButton.CENTER);
    btn_2.setFont(new Font("Calibri", Font.BOLD, 14));
    btn_2.setPreferredSize(new Dimension(80, 80));

    if(flagnum2==0)
    {   btn_2.setEnabled(false);    }

    btn_2.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
        try{
                if(flagnum2==1)
                {
                    if(num2!=null)
                    {
                        buttonname = prodbutton.get(1).get("prodname");
                        //quantity_panel qp = new quantity_panel();
                    }
                }

            }catch (Exception e) {}
        }
    });
    panel_1.add(btn_2);

    btn_3 = new JButton("<html><p align=center>"+num3+"</p></html>");
    //btn_3.setIcon(new ImageIcon("more_buttons\\lightblue.png"));
    //btn_3.setBorderPainted(false);  
            //btn_3.setFocusPainted(false);
            //btn_3.setContentAreaFilled(false); 
            //btn_3.setHorizontalTextPosition(JButton.CENTER);
    btn_3.setFont(new Font("Calibri", Font.BOLD, 14));
    btn_3.setPreferredSize(new Dimension(80, 80));

    if(flagnum3==0)
    {   btn_3.setEnabled(false);    }

    btn_3.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            try{
                if(flagnum3==1)
                {
                    if(num3!=null)
                    {
                        buttonname = prodbutton.get(2).get("prodname");
                        //quantity_panel qp = new quantity_panel();
                    }
                }

            }catch (Exception e) {}
        }
    });
    panel_1.add(btn_3);



    Card.add(panel_1);
}


    public static String Capitalize(String text)
{

    String tmp[] = text.split(" ");
    int ctr=tmp.length;
    if(tmp.length>3)
    {ctr=3;}
    text="";

    for(int i=0; i<ctr; i++)
    {
        String firstLetter = tmp[i].substring(0,1).toUpperCase();
        String restLetters = tmp[i].substring(1).toLowerCase();
        String converted = firstLetter + restLetters;

        if (converted.length()>6)
        {
            converted = converted.substring(0,6)+"..";
        }

        if(i!=(ctr-1))
        {
            text = text+converted+"<br/>";
        }
        else
        {
            text = text+converted;
        }
    }

    return text;

  }

    public static ArrayList<HashMap<String, String>> getProductsButton(int groupnum) {

            ArrayList<HashMap<String, String>> prodbutton = new         ArrayList<HashMap<String, String>>();
            HashMap<String, String> tmp = new HashMap<String,String>();
            tmp.put("A","A");   
            tmp.put("B","B");
            tmp.put("C","C");
            prodbutton.add(tmp);

        return prodbutton;
            }

public static void main(String[] args) {
     EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
           Buttonrepaint test = new Buttonrepaint();
        }
    });
}

}

Это должно быть так:

Изображение 174551

Когда я нажимаю кнопку далее, синие кнопки должны быть перекрашены серым цветом, и у меня уже есть флаг для этого, и моя единственная проблема в том, что при нажатии следующей кнопки кнопки не перерисовываются. Ничего не изменилось, кроме метки Back. Я здесь что-то не так?

РЕДАКТИРОВАТЬ

Я разместил там код. Скорее всего, так. Он работает, но не HashMap. Ну, я не знаю об этом, но я думаю, что это сработает, если настроен HashMap. Исходный HashMap который находится в моем коде, подключен к базе данных. И так. Причина, по которой кнопки отключены, заключается в том, что у них нет имен, которые должны появиться из HashMap и поскольку я не знаю, как это сделать, это будет так. Во всяком случае, моя проблема заключается в том, что при нажатии следующей кнопки имена из ArrayList будут изменены на второй набор Arrays. Причина, по которой я buttonGroup++; если кнопка нажата, второй набор Arrays будет отображаться на 3 кнопках. И так. Моя проблема в том, что когда я нажимаю на следующую кнопку, названия кнопок остаются теми же, но значения изменились. Поэтому я хочу перерисовать кнопки так, чтобы они обновлялись.

  • 0
    Подумайте о предоставлении работающего примера, который демонстрирует вашу проблему. Это приведет к меньшему беспорядку и лучшим ответам
  • 0
    AFAIK, есть / не проблема с JButton & Icon & Html вместе, нужно отладить, как yout ButtonGroup работает больше ничего, для SSCCE / MCVE использовать UIManager.getIcon ("OptionPane.errorIcon")
Показать ещё 9 комментариев
Теги:
swing
jbutton
repaint

2 ответа

2

Поскольку siwng основан на модели MVC, вы должны сосредоточиться на моделях вместо компонентов ui. Я думаю, что это упростит, потому что вы просто меняете модели, а компоненты ui автоматически переписывают себя.

Поэтому я предпочел бы следующий путь, потому что он позволяет вам легко или просто изменить поведение кнопки " Next/Back.

public class Main {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setSize(400, 80);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        final Container contentPane = frame.getContentPane();
        contentPane.setLayout(new FlowLayout());

        JButton buttonA = new JButton("A");
        JButton buttonB = new JButton("B");
        JButton buttonC = new JButton("C");

        ButtonGroup buttonGroup = new ButtonGroup();
        buttonGroup.add(buttonA);
        buttonGroup.add(buttonB);
        buttonGroup.add(buttonC);

        ButtonGroupVisibilityToggleChange toggleChange = new ButtonGroupVisibilityToggleChange();
        ButtonGroupToggleAction toggleAction = new ButtonGroupToggleAction(
                buttonGroup, toggleChange);

        JButton buttonGroupVisibilityButton = new JButton(toggleAction);

        contentPane.add(buttonGroupVisibilityButton);
        contentPane.add(buttonA);
        contentPane.add(buttonB);
        contentPane.add(buttonC);

        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

}

Для этого я бы сначала создал интерфейс, представляющий логику, которая будет выполняться при событии переключения.

interface ButtonGroupToggleChange {
    public boolean toggle(ButtonGroup buttonGroup, boolean actualToggleState);
}

И чем я создаю реализацию, чтобы изменить видимость ButtonGroup на событие переключения.

class ButtonGroupVisibilityToggleChange implements ButtonGroupToggleChange {

    public boolean toggle(ButtonGroup buttonGroup, boolean actualToggleState) {
        boolean nextVisibleState = !actualToggleState;
        Enumeration<AbstractButton> buttons = buttonGroup.getElements();
        while (buttons.hasMoreElements()) {
            AbstractButton abstractButton = buttons.nextElement();
            abstractButton.setVisible(nextVisibleState);
            Container parent = abstractButton.getParent();
            if (parent != null) {
                parent.revalidate();
            }
        }

        return nextVisibleState;
    }
}

И, наконец, я создаю Action который обрабатывает состояние переключения и выполняет ButtonGroupChange

class ButtonGroupToggleAction extends AbstractAction {

    private static final long serialVersionUID = -1345619745031378545L;

    private ButtonGroup buttonGroup;
    private boolean toggleState = true;
    private String toggleOnName = "Hide";
    private String toogleOffName = "Show";

    private ButtonGroupToggleChange buttonGroupToggleChange;

    public ButtonGroupToggleAction(ButtonGroup buttonGroup,
            ButtonGroupToggleChange buttonGroupToggleChange) {
        this.buttonGroup = buttonGroup;
        this.buttonGroupToggleChange = buttonGroupToggleChange;
        executeToggleButtonChange();
    }

    public void actionPerformed(ActionEvent e) {
        executeToggleButtonChange();
    }

    private void executeToggleButtonChange() {
        toggleState = buttonGroupToggleChange.toggle(buttonGroup, toggleState);
        setToggleName(toggleState);
    }

    public String getToggleOnName() {
        return toggleOnName;
    }

    public void setToggleOnName(String toggleOnName) {
        this.toggleOnName = toggleOnName;
        setToggleName(toggleState);
    }

    public String getToogleOffName() {
        return toogleOffName;
    }

    public void setToogleOffName(String toogleOffName) {
        this.toogleOffName = toogleOffName;
        setToggleName(toggleState);
    }

    private void setToggleName(boolean visible) {
        if (visible) {
            putValue(Action.NAME, toggleOnName);
        } else {
            putValue(Action.NAME, toogleOffName);
        }
    }
}
  • 0
    согласен, но почему бы не использовать JToggleButton и тестировать только для isSelected (а не для ButtonGroupToggleAction), а у OP есть проблема с добавлением JComponent во время выполнения, тогда все смешалось
  • 0
    Я не использовал JToggleButton потому что OP его не использовал. Я думаю, что ОП не хочет, чтобы кнопка оставалась нажатой, если она находится в выбранном состоянии. Тем не менее можно использовать ToggleButtonModel .
Показать ещё 1 комментарий
1

Когда вы нажмете кнопку "Далее", ActionListener зарегистрированный на этой кнопке.

Это зарегистрированный ActionListener (ваш код):

public void actionPerformed(ActionEvent arg0) {
        buttonGroup++;

        if(prodbutton!=null)
        {
            btnGroup3.setText("Back");
            prodbutton.clear();
            stat=1;
            btn_1.repaint(); // button here should refresh
        }
        else
        {
            System.out.println("EMPTY!!!!!");
            buttonGroup--;
            stat=0;
        }
    }

В этом вы не вносите никаких изменений в "синие" кнопки (btn_1), поэтому не имеет значения, перерисовываете их или нет, они будут (повторно) нарисованы одинаково.

  • 0
    пожалуйста, btn_1.repaint (); ??? ... я думаю, что нет
  • 0
    Я только что процитировал из кода спрашивающего. Это не мой код и не предлагаемое решение - просто указание на btn_1 не изменяется.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню