Что-то в этом роде? ;)
Проблема у вас есть то, что это чрезвычайно болезненным переопределить Nimbus' цвета по умолчанию для конкретного экземпляра компонента (см в related question).
Большинство художников Nimbus определяют около 50 различных цветов, полученных из одного или двух основных (nimbusBlueGrey
и известных nimbusOrange
). Лучшим способом было бы переопределить их в UIDefaults
, найденном в Nimbus.Override
, свойства компонента, который вы хотите изменить, но это не то, что они сделали (я хотел бы открыть ошибку на этом;), серьезно!).
Я пытаюсь достичь того же самого и, наконец, смог ... (закройте глаза), скопировав и взломав класс javax.swing.plaf.nimbus.ProgressBarPainter
в мой собственный код! Зачем? Поскольку этот класс является приватным для пакета и не может быть переопределен (это было бы немного чище ...). Столько, сколько я ненавижу , чтобы сделать это, он работал ...
Вот как изменить его (я не буду размещать весь код, как это слишком большой и не так интересно):
Начните с добавления следующих методов после конструктора ProgressBarPainter()
. (Они в основном копипаст, что вы можете найти следующий метод decodeColor()
до AbstractRegionPainter
затем NimbusLookAndFeel
затем NimbusDefaults.getDerivedColor()
и, наконец DerivedColor.rederiveColor()
):
private float clamp(float v) {
if (v < 0.0f)
return 0.0f;
if (v > 1.0f)
return 1.0f;
return v;
}
private int clamp(int v) {
if (v < 0)
return 0;
if (v > 255)
return 255;
return v;
}
// Got from javax.swing.plaf.nimbus.DerivedColor.rederiveColor()
private Color decodeColor(Color src, float hOffset, float sOffset, float bOffset, int aOffset) {
float[] tmp = Color.RGBtoHSB(src.getRed(), src.getGreen(), src.getBlue(), null);
tmp[0] = clamp(tmp[0] + hOffset);
tmp[1] = clamp(tmp[1] + sOffset);
tmp[2] = clamp(tmp[2] + bOffset);
int alpha = clamp(src.getAlpha() + aOffset);
return new Color((Color.HSBtoRGB(tmp[0], tmp[1], tmp[2]) & 0xFFFFFF) | (alpha << 24), true);
}
Скопируйте и вставьте код статически, генерирующего 50 цветов к способу вы будете использовать для их создания динамически, от цвета вы хотите:
от:
private Color color1 = decodeColor("nimbusBlueGrey", 0.0f, -0.04845735f, -0.17647058f, 0);
...
private Color color50 = decodeColor("nimbusOrange", 0.0014062226f, -0.77816474f, 0.12941176f, 0);
To:
private void initColors(Color foreground) {
color1 = decodeColor("nimbusBlueGrey", 0.0f, -0.04845735f, -0.17647058f, 0);
// ...
color50 = decodeColor(foreground, 0.0014062226f, -0.77816474f, 0.12941176f, 0);
}
Обратите внимание, что мы передаем цвет, который мы хотим в качестве параметра и использовать его в качестве замены nimbusOrange
, который, кажется, основной цвет для прогресса баров. Мы стараемся придерживаться способа получения цветов Нимбусом.
И изменить ProgressBarPainter()
конструктор включить основной цвет и генерировать их:
public ProgressBarPainter(int state, Color foreground) {
super();
this.state = state;
this.ctx = new AbstractRegionPainter.PaintContext(new Insets(5, 5, 5, 5), new Dimension(29, 19), false);
initColors(foreground); // Generates appropriate colors
}
Вы найдете как инициализировать ctx
поле в источнике NimbusDefaults
. Однако обратите внимание, что перечисление AbstractRegionPainter.PaintContext.CacheMode
не видно из измененного класса, поэтому вы не сможете использовать все привлекательные функции. К счастью, есть более простой конструктор до AbstractRegionPainter.PaintContext
, который не использует его. (В моем случае мне не нужны все разные состояния, поэтому я использовал значения по умолчанию, но не стесняйтесь добавлять любые другие параметры, чтобы справиться с ними).
И, наконец, Грааль! ;) (меняет цвет в соответствии со значением, которое должно быть в процентах: green
, если более 75%, orange
, если более 50% и red
в противном случае).
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
int v = ((Integer)value).intValue();
Color c;
if (val >= 75)
c = Color.GREEN;
else if (val >= 50)
c = Color.ORANGE;
else
c = Color.RED;
setValue(v);
UIDefaults defaults = new UIDefaults();
ProgressBarPainter painter = new ProgressBarPainter(ProgressBarPainter.FOREGROUND_ENABLED, c);
defaults.put("ProgressBar[Enabled].foregroundPainter", painter);
putClientProperty("Nimbus.Overrides", defaults);
return this;
}
Теперь, давайте «чистый», что немного (так же, как мы можем назвать это «чистая» работа):
- удалить задания для
private Color colorXX
, которые используют nimbusOrange
, так как они будет вызван вызовом initColors()
.
- Сохраните присвоения для них, которые используют
nimbusBlueGrey
, так как мы их не меняем, и не включаем их в initColors()
. Это дает вам initColors()
, генерирующий 26 цветов (от 17 до 28, 30, от 33 до 44 и 50).
- если, как я, у вас есть только несколько цветов, чтобы представлять для всех вас прогресс баров, прегенерация все
ProgressBarPainter
s вы будете когда-либо использовать и назначить правильный в getTableCellRendererComponent()
- (или в моем случае создания три
private static JProgressBar red, orange, green
с соответствующими перекрываться цветными художниками и вернуть их вместо this
в getTableCellRendererComponent()
)
Кто-нибудь может помочь? – mbasol