Как установить фон JButton? - PullRequest
2 голосов
/ 10 февраля 2020

Я пытаюсь установить цвет JButton со свойствами в NetBeans, но безуспешно. Когда я выбираю цвет, меняется только цвет рамки:

enter image description here

Я читал об этом, и я думаю, что это связано с моим внешним видом , Я создал проект в Netbans как «Java Настольное приложение», и я думаю, что я использую Nimbus:

public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(Entrenamiento.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(Entrenamiento.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(Entrenamiento.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(Entrenamiento.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the dialog */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            Entrenamiento dialog = new Entrenamiento(new javax.swing.JFrame(), true);
            dialog.addWindowListener(new java.awt.event.WindowAdapter() {
                @Override
                public void windowClosing(java.awt.event.WindowEvent e) {
                    System.exit(0);
                }
            });
            dialog.setVisible(true);
        }
    });
}

Я попытался установить фон JButton следующим образом: UIManager.put("Button.background", Color.WHITE);

Однако это не работает. Как мне этого добиться? Спасибо.

Ответы [ 3 ]

1 голос
/ 13 марта 2020

Настроенная Java L & F является в настоящее время проблемой для сообществ (таких как JFormDesigner) или программистов с открытым исходным кодом (таких как я).

Настройка java l & f java возможна из трех методов Например:

  • с использованием UIManager
  • Использование персонального интерфейса компонентов
  • с использованием ручной настройки.

Настройка UIManager

Это более сложно и непросто, потому что разные l & f используют разные свойства внутри карты. Кроме того, вы можете совершать ошибки внутри строки di git, например «button.background», а не «Button.background».

Использование пользовательского интерфейса компонента

Вы можете использовать персональный компонент Пользовательский интерфейс, как и внутри этот ответ , но это имеет смысл с пользовательским изменением, потому что если вы измените l & f на время выполнения, вы потеряете этот личный l & f.

ex: вы хотите указать c кнопка без эффекта мыши над эффектом или без рамки

Создайте ручную настройку стиля.

Вы можете использовать ручную настройку, например, ответ , этот метод не Это хорошо, потому что вы должны организовать код с помощью таких методов или компонентов, как

public void configureStyle(String theme){
  //some code
}

Почему метод для настройки стиля? потому что если вы реализуете возможность изменять l & f внутри вашего проекта без этих методов или компонентов, вы теряете свои личные настройки.

т.е.: у вас должен быть метод для сброса всех личных свойств.

Заключение

Я хочу добавить заключение к моему ответу: если вы разрабатываете новый проект, я думаю, что вы можете использовать новый l & f в качестве основы вашего проекта, и если вы будете искать его на Github, вы можете найти много нового л & ф. Но я хочу рассказать в своем ответе один из моих проектов, названный MaterialTheming и реализованный внутри Material-UI-Swing

MaterialTheming

MaterialTheming - это второй слой для материала- ui-swing l & f это состоит в том, чтобы реализовать компонент со всей конфигурацией l & f. Конфигуратор этого компонента называется theme .

Итак, в настоящий момент MaterialTheming находится в альфа-версии и поддерживает только процессуальная постановка. Кроме того, с помощью MaterialTheming вы можете разработать свою личную тему, и у вас есть полный контроль над стилем L & F.

У меня есть разработчик, необходимый для реализации облегченной и темной темы с тем же интерфейсом и методами внутри. java Я написал много кода внутри моего клиентского приложения (это плохой выбор, потому что GUI приложения).

Первый (частичный пример) личной темы - this MaterialDarkPinkTheme

Итак, чтобы реализовать тему для вашего приложения, чтобы изменить цветную кнопку по умолчанию, код выглядит так:

import mdlaf.themes.MaterialLiteTheme;
import mdlaf.utils.MaterialColors;

/**
 * @author https://github.com/vincenzopalazzo
 */
public class PersonalMaterialTheme extends MaterialLiteTheme {

    @Override
    protected void installColor() {
        super.installColor();
        super.buttonBackgroundColor = MaterialColors.AMBER_800;
        super.buttonBackgroundColorMouseHover = MaterialColors.AMBER_500;
        super.buttonDefaultBackgroundColor = MaterialColors.COSMO_ORANGE;
    }
}

Эффект такой:

enter image description here

0 голосов
/ 20 февраля 2020

Может быть, это глупый вопрос, но вы пытались просто установить цвет фона с помощью кода? Как это:

yourButton.setOpaque(true);
yourButton.setBackground(Color.WHATEVER);
0 голосов
/ 13 февраля 2020

Хорошо, я наконец понял, этот Windows интерфейс действительно трудно изменить. Поэтому, если вы хотите использовать Nimbus Look and Feel, вы должны выяснить, почему он заменен Windows Look and Feel. Но если вы хотите придерживаться Windows L & F, вы можете определить новый пользовательский интерфейс для класса Button, который похож на WindowsButtonUI, но учитывает цвет фона. Для этого я создал класс пользовательского интерфейса, который вызывает Windows L & F, если доступно. Это было особенно сложно, потому что Windows L & F и все его классы не входят в стандартный дистрибутив и поэтому не могут использоваться в исходном коде, поэтому нет расширений с переопределениями, просто делегирование с отражением. Я расширил его, позволив рисовать WindowsButtonUI в буфере, затем заменив цвет кнопки windows на заданный цвет фона, но оставив все эффекты нарисованными поверх фона (эти синие эффекты при выборе, нажмите et * 1023). *.). Также по-прежнему рисует немного более темную границу, но теперь с немного более темной версией вашего собственного цвета. В то время как код противоположен тому, что вы должны сделать (с большим количеством вызовов отражения) , а замена цвета, похоже, не делает точно того, что я ожидал (исправил проблему ) , я думаю, что результат выглядит довольно хорошо. Примечание: это может выглядеть действительно странно в любой операционной системе, кроме Windows. Чтобы установить новый пользовательский интерфейс и цвет, выполните:

UIManager.put("Button.background", Color.WHITE);
UIManager.put("ButtonUI", CustomWindowsButtonUI.class.getCanonicalName());

И исходный код CustomWindowsButtonUI:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.lang.reflect.Method;

import javax.swing.AbstractButton;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicButtonUI;
import javax.swing.plaf.metal.MetalButtonUI;

import com.sun.java.swing.plaf.windows.WindowsGraphicsUtils;

import sun.awt.AppContext;

@SuppressWarnings("restriction")
public class CustomWindowsButtonUI extends BasicButtonUI {

    private final static Color WINDOWS_BUTTON_COLOR = new Color(225, 225, 225);

    private BasicButtonUI delegateUI;
    private Class<?> windowsUIClass = null;
    private boolean isWindows = false;

    private static final Object CUSTOM_WINDOWS_BUTTON_UI_KEY = "CUSTOM_WINDOWS_BUTTON_UI_KEY";

    public CustomWindowsButtonUI() {
        try {
            windowsUIClass = Class.forName("com.sun.java.swing.plaf.windows.WindowsButtonUI");
            delegateUI = (BasicButtonUI) windowsUIClass.getConstructor().newInstance();
            isWindows = true;
        } catch (Throwable e) {
            System.err.println("Failed to locate windows button ui, defaulting to MetalUI (Swing default).");
            delegateUI = new MetalButtonUI();
        }
    }

    public static ComponentUI createUI(JComponent c) {
        AppContext appContext = AppContext.getAppContext();
        CustomWindowsButtonUI customWindowsButtonUI = (CustomWindowsButtonUI) appContext.get(CUSTOM_WINDOWS_BUTTON_UI_KEY);
        if (customWindowsButtonUI == null) {
            customWindowsButtonUI = new CustomWindowsButtonUI();
            appContext.put(CUSTOM_WINDOWS_BUTTON_UI_KEY, customWindowsButtonUI);
        }
        return customWindowsButtonUI;
    }

    @Override
    public void update(Graphics g, JComponent c) {
        paint(g, c);
    }

    @Override
    public void paint(Graphics g, JComponent c) {
        if (isWindows) {
            int width = c.getWidth();
            int height = c.getHeight();
            BufferedImage paintBufferImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            delegateUI.paint(paintBufferImage.createGraphics(), c);
            Color backgroundColor = c.getBackground();
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    Color pixelColor = new Color(paintBufferImage.getRGB(x, y), true);
                    Color targetColor = new Color(getTargetColorValue(pixelColor.getRed(), WINDOWS_BUTTON_COLOR.getRed(), backgroundColor.getRed()),
                            getTargetColorValue(pixelColor.getGreen(), WINDOWS_BUTTON_COLOR.getGreen(), backgroundColor.getGreen()),
                            getTargetColorValue(pixelColor.getBlue(), WINDOWS_BUTTON_COLOR.getBlue(), backgroundColor.getBlue()), pixelColor.getAlpha());
                    paintBufferImage.setRGB(x, y, targetColor.getRGB());
                }
            }
            g.drawImage(paintBufferImage, 0, 0, null);
        } else {
            delegateUI.paint(g, c);
        }
    }

    private static int getTargetColorValue(int value, int subtract, int add){
        return Math.min(255, Math.max(0, value - subtract + add));
    }

    protected void installDefaults(AbstractButton b) {
        try {
            Method method = windowsUIClass.getDeclaredMethod("installDefaults", AbstractButton.class);
            method.setAccessible(true);
            method.invoke(delegateUI, b);
        } catch (Throwable e) {
            System.err.println("Failed to call delegate installDefaults: " + e.getClass().getName() + " - " + e.getMessage());
            super.installDefaults(b);
        }
    }

    protected void uninstallDefaults(AbstractButton b) {
        try {
            Method method = windowsUIClass.getDeclaredMethod("uninstallDefaults", AbstractButton.class);
            method.setAccessible(true);
            method.invoke(delegateUI, b);
        } catch (Throwable e) {
            System.err.println("Failed to call delegate uninstallDefaults: " + e.getClass().getName() + " - " + e.getMessage());
            super.uninstallDefaults(b);
        }
    }

    // copied from WindowsButtonUI
    protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) {
        WindowsGraphicsUtils.paintText(g, b, textRect, text, getTextShiftOffset());
    }

    protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect, Rectangle textRect, Rectangle iconRect) {
        try {
            Method method = windowsUIClass.getDeclaredMethod("paintFocus", Graphics.class, AbstractButton.class, Rectangle.class, Rectangle.class, Rectangle.class);
            method.setAccessible(true);
            method.invoke(delegateUI, g, b, viewRect, textRect, iconRect);
        } catch (Throwable e) {
            System.err.println("Failed to call delegate paintFocus: " + e.getClass().getName() + " - " + e.getMessage());
            super.paintFocus(g, b, viewRect, textRect, iconRect);
        }
    }

    // copied from WindowsButtonUI
    protected void paintButtonPressed(Graphics g, AbstractButton b) {
        setTextShiftOffset();
    }

    // copied from WindowsButtonUI
    public Dimension getPreferredSize(JComponent c) {
        Dimension d = super.getPreferredSize(c);
        AbstractButton b = (AbstractButton) c;
        if (d != null && b.isFocusPainted()) {
            if (d.width % 2 == 0) {
                d.width += 1;
            }
            if (d.height % 2 == 0) {
                d.height += 1;
            }
        }
        return d;
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...