Как гласит название, можно ли каким-либо образом перекрасить 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();
}
});
}
}
Это должно быть так:
Когда я нажимаю кнопку далее, синие кнопки должны быть перекрашены серым цветом, и у меня уже есть флаг для этого, и моя единственная проблема в том, что при нажатии следующей кнопки кнопки не перерисовываются. Ничего не изменилось, кроме метки Back. Я здесь что-то не так?
РЕДАКТИРОВАТЬ
Я разместил там код. Скорее всего, так. Он работает, но не HashMap
. Ну, я не знаю об этом, но я думаю, что это сработает, если настроен HashMap
. Исходный HashMap
который находится в моем коде, подключен к базе данных. И так. Причина, по которой кнопки отключены, заключается в том, что у них нет имен, которые должны появиться из HashMap
и поскольку я не знаю, как это сделать, это будет так. Во всяком случае, моя проблема заключается в том, что при нажатии следующей кнопки имена из ArrayList
будут изменены на второй набор Arrays
. Причина, по которой я buttonGroup++;
если кнопка нажата, второй набор Arrays
будет отображаться на 3 кнопках. И так. Моя проблема в том, что когда я нажимаю на следующую кнопку, названия кнопок остаются теми же, но значения изменились. Поэтому я хочу перерисовать кнопки так, чтобы они обновлялись.
Поскольку 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);
}
}
}
JToggleButton
потому что OP его не использовал. Я думаю, что ОП не хочет, чтобы кнопка оставалась нажатой, если она находится в выбранном состоянии. Тем не менее можно использовать ToggleButtonModel
.
Когда вы нажмете кнопку "Далее", 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
), поэтому не имеет значения, перерисовываете их или нет, они будут (повторно) нарисованы одинаково.
btn_1
не изменяется.