Nimbus ProgressBar Colors

Highchiller

Bekanntes Mitglied
Hallo Leute,

ich hab mal wieder eine Nimbus frage an euch. Angeblich soll es ja so leicht sein die DefaultWerte von Nimbus zu ändern aber ich find nicht raus wie ich meine Änderungen hinbekommen.

Meine JProgressBar ist im Nimbus Look and Feel. Das gefällt mir gut, aber wenn ich einen Text hinzufüge ist dieser auch schwarz wenn sich die Bar füllt. Schwarze Schrift auf dunkel-Orangen Hintergrund ist aber nicht gut zu lesen.

Wie ich die Schriftfarbe anpassen könnte ist hier super gelöst:
Change Textcolor of progressBar

Aber wenn ich von BasicProgressBarUI erbe dann ist die ProgressBar ja komplett abgeändert. Ich will aber die NimbusProgressBar nur mit den weißer Schrift wenn die Bar gefüllt ist, ansonsten schwarz.

Ich hoffe ihr könnt mir helfen.

Ich glaub Code ist hier nicht zwingen nötig.
Vielen Dank schon mal :)

PS: Am besten wäre natürlich das für alle JProgressBars gleichzeitig zu ändern. Aber eine lokale Lösung würde mich auch erst mal reichen.
 

Highchiller

Bekanntes Mitglied
Also ich bekomme immerhin die Schrift weiß:

Java:
/* Die Imports kommen aus:
javax.swing.UIDefaults;
javax.swing.UIManager;
*/
  //... irgendwo weit vorher wurde das LookAndFeel auf Nimbus gesetzt
  UIDefaults defaults = UIManager.getLookAndFeelDefaults();
  defaults.put("ProgressBar[Enabled].textForeground", Color.WHITE);
  
  // this ist hier die JProgressBar in der ich mich befinde
  this.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
  this.putClientProperty("Nimbus.Overrides", defaults);

Nun ist halt der ganze Text weiß unabhängig vom Hintergrund. Der Anfangspost hat ja angedeutet das es möglichkeiten gibt das so abzuändern, wenn man sich mit der BasicProgressBarUI zufrieden gibt schauts echt easy aus:
Java:
setUI(new BasicProgressBarUI() {
      protected Color getSelectionBackground() { return Color.black; }
      protected Color getSelectionForeground() { return Color.white; }
    });
Setting the colors of a JProgressBar text

Ich find einfach keinen Weg... :bahnhof: Gibts nicht irgendwie eine Möglichkeit vom NimbusLookAndFeel der ProgressBarUI zu erben? Sowas wie ne Klasse NimbusProgressBarUI gibts ja leider nicht...

Ich hoffe ihr kommt weiter als ich :/

Grüße
Highchiller
 

X5-599

Top Contributor
Leider gibt es keinen einfachen Weg. Bei meinen Recherchen bin ich soweit gekommen, dass das Nimbus Look and Feel das SynthProgressBarUI benutzt. Die Klasse ist package private also kann man da nichts überschreiben. Dann wird das NimbusStyle benutzt. Das ist wiederum eine final Klasse. Auch nichts mit überschreiben. Also wenn die Macher vorhatten dass da BLOSS keiner was anpasst haben sie ihr Ziel mehr als erfüllt. Ich habe jedenfalls bis jetzt keine Möglichkeit gefunden da irgendwo anzugreifen.
Wenn jemand mehr Erfolg hatte, oder andere Erkenntnisse hat würde ich mich über eine Nachhilfestunde freuen.
 

Highchiller

Bekanntes Mitglied
Oh man, das ist ja ärgerlich -.-

Könnte man irgendwie wild rumtricksen indem man drüber zeichnet?
Auch wenn ich grad keine Ahnung habe wie ich das am ehesten realisiere exakt 2 ProgressBars übereinander zu legen, die obere durchsichtig zu machen und nur den Text zu zeichnen...

Moaaaaaan
 

X5-599

Top Contributor
Reflection habe ich auch drüber nachgedacht. Bin aber nicht weit gekommen. (und fände das auch ziemlich unschön...)
Ansonsten, drüber zeichnen hört sich eigentlich gut an. Willst du normale JProgressBars benutzen, oder kann das auch eine eigene Klasse sein, die JProgressBar beerbt?

Für "normale" JProgressBars könntest du sowas machen:
Java:
private static JProgressBar createProgressBar(final String text)
{
	@SuppressWarnings("serial")
	JProgressBar pr = new JProgressBar() {
			
		@Override
		protected void paintComponent(Graphics g)
		{
			super.paintComponent(g);
				
			Rectangle bounds = getBounds();
			FontMetrics fm = g.getFontMetrics();
			Rectangle2D rect = fm.getStringBounds(text, g);
				
			int x = (int)((bounds.width / 2) - (rect.getWidth() / 2));
			int y = (bounds.height / 2) + ((fm.getAscent()+fm.getDescent())/2);
				
			g.setColor(Color.WHITE);
			g.drawString(text, x, y-3);
		}
	};
		
	return pr;
}

So hast du natürlich immer einen weissen Text. Um die Farbe anzupassen, wenn z.B. der ProgressBar drübergelaufen ist, bedarf es schon etwas mehr Arbeit.


EDIT: Ach, ich seh' gerade man kann auch einfach folgendes machen:
Java:
JProgressBar progress = new JProgressBar();
progress.setForeground(Color.WHITE);

Da ist dann auch der ganze Text immer weiss. Nimbus ändert die Farbe anscheinend auch nie in Abhängigkeit des Füllstandes...
 
Zuletzt bearbeitet:

Highchiller

Bekanntes Mitglied
Naja wie gesagt, den ganzen Text auf einmal weiß zu bekommen ginge ja so:
Java:
/* Die Imports kommen aus:
javax.swing.UIDefaults;
javax.swing.UIManager;
*/
  //... irgendwo weit vorher wurde das LookAndFeel auf Nimbus gesetzt
  UIDefaults defaults = UIManager.getLookAndFeelDefaults();
  defaults.put("ProgressBar[Enabled].textForeground", Color.WHITE);
  
  // this ist hier die JProgressBar in der ich mich befinde
  this.putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
  this.putClientProperty("Nimbus.Overrides", defaults);

Aber ich glaub das übermalen ist gar nicht so schlecht. :bloed:
Meinste ich könnte dem Graphics-Object jetzt noch ein Clipping geben damit er nur mit Weiß übermalt wo auch die ProgressBar ausgefüllt ist und damit die restliche Schrift (schwarz) nicht übermalt? Das Clipping kann ja praktischer Weise ein simples Rectangle sein.
Oder versteh ich clip(Shape s) aus Graphics falsch?

Ich konnts noch nicht testen aber das klingt mir nach der (wenn auch umständlichen) Lösung :applaus:

Grüße
Highchiller

PS: Ja ich erbe sowieso von der JProgressBar also wird das ganze noch aufgeräumter :)
 

X5-599

Top Contributor
Dann habe ich was für dich. Ich habe mich dreisterweise beim BasicProgressBarUI bedient, was das Zeichnen anging :). Mit clip() wird da gearbeitet. Ist eigentlich ganz verständlich, auch wenn ich noch nie damit gearbeitet habe. Die Positionierung ist komplett von mir. Die ließ sich nicht übernehmen, da das BasicProgressBarUI gerne mit SwingUtilities2 arbeitet...
Was hälst du davon?

Java:
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;

import javax.swing.BoundedRangeModel;
import javax.swing.JProgressBar;


public class MyJProgressBar2 extends JProgressBar
{
	private static final long serialVersionUID = 7011699579650095776L;
	private boolean stringPaintedOverride = false;
	private Color textColorOutsidePaint = Color.BLACK;
	private Color textColorInsidePaint = Color.WHITE;
	
	public MyJProgressBar2()
	{
		setStringPainted(false);
	}
	
	@Override
	protected void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		
		if(stringPaintedOverride)
		{
			drawString(g);
		}
	}
	
	@Override
	public void setStringPainted(boolean painted)
	{
		super.setStringPainted(false);
		setStringPaintedOverride(painted);
	}
	
	private void setStringPaintedOverride(boolean stringPaintedOverride)
	{
		this.stringPaintedOverride = stringPaintedOverride;
	}
	
	public void setTextColorOutsidePaint(Color textColorOutsidePaint)
	{
		this.textColorOutsidePaint = textColorOutsidePaint;
	}
	
	public void setTextColorInsidePaint(Color textColorInsidePaint)
	{
		this.textColorInsidePaint = textColorInsidePaint;
	}
	
	private void drawString(Graphics g)
	{
		g.setFont(getFont());
		Rectangle oldClip = g.getClipBounds();
		
		Insets b = getInsets(); // area for border
		int barRectWidth = getWidth() - (b.right + b.left);
		int barRectHeight = getHeight() - (b.top + b.bottom);
		
		int amountFull = 0;
		BoundedRangeModel model = getModel();
		
		if ( (model.getMaximum() - model.getMinimum()) != 0) {
		    if (getOrientation() == JProgressBar.HORIZONTAL) {
		        amountFull = (int)Math.round(barRectWidth *
						     getPercentComplete());
		    } else {
		        amountFull = (int)Math.round(barRectHeight *
						     getPercentComplete());
		    }
		}
		
		int fillStart;
		Point renderLocation = getStringPlacement(g);
		
		if (getOrientation() == JProgressBar.HORIZONTAL)
		{
			if(getComponentOrientation().isLeftToRight())
				fillStart = b.left;
			else
				fillStart = b.left + barRectWidth - amountFull;
			
		    g.setColor(textColorOutsidePaint);
		    drawString(g, renderLocation.x, renderLocation.y);
		    
		    g.setColor(textColorInsidePaint);
	        g.clipRect(fillStart, b.top, amountFull, barRectHeight);
		    drawString(g, renderLocation.x, renderLocation.y);
		}
		else
		{
			// VERTICAL
			fillStart = b.top + barRectHeight - amountFull;
			
	        AffineTransform rotate = AffineTransform.getRotateInstance(Math.PI / 2);
	        g.setFont(getFont().deriveFont(rotate));
	        g.setColor(textColorOutsidePaint);
		    drawString(g, renderLocation.x, renderLocation.y);
		    
		    g.setColor(textColorInsidePaint);
		    g.clipRect(b.left, fillStart, barRectWidth, amountFull);
		    drawString(g, renderLocation.x, renderLocation.y);
		}
		
		g.setClip(oldClip);
	}
	
	private Point getStringPlacement(Graphics g)
	{
		FontMetrics fontSizer = getFontMetrics(getFont());
		if (getOrientation() == JProgressBar.HORIZONTAL)
		{
			int x = (getWidth() / 2) - (int)Math.round(fontSizer.getStringBounds(progressString, g).getWidth() / 2);
			int y = (getHeight() - (int)Math.round((getHeight()-fontSizer.getStringBounds(progressString, g).getHeight()) / 2)) - 3;
			return new Point(x, y);
		}
		else
		{
			// VERTICAL
			int x = ((getWidth() / 2) - (int)Math.round(fontSizer.getStringBounds(progressString, g).getHeight() / 2)) + 4;
			int y = (int)Math.round((getHeight() - fontSizer.getStringBounds(progressString, g).getWidth()) / 2);
			return new Point(x, y);
		}
	}
	
	private void drawString(Graphics g, int x, int y)
	{
		if(g != null)
		{
			if(isIndeterminate())
				g.setColor(Color.BLACK);
			
			g.drawString(progressString, x, y);
		}
	}
}

EDIT: Ich sehe gerade Zeile 22 kannst du rausnehmen. Ist unwichtig, da paintString sowiso standardmäßig false ist.
 
Zuletzt bearbeitet:

Highchiller

Bekanntes Mitglied
Hey X5-599,

na Mensch! Das ist doch Prima :) Das ist obendrein gleich noch viel mehr als ich gebraucht hätte. Ich glaub das kann in den CodeSchnippsel bereich verschobene werden, sowas gibts doch hier :)

Gefällt mir sehr gut. Ich konnts noch nicht testen aber so wie ich den Code-Lese schauts richtig gut aus. Da müsste sogar das Nimbus LookAndFeel erhalten bleiben o_O

Wenn sich noch Probleme auftun meld ich mich noch mal.

Vielen Dank noch mal :) Das hat mir extrem geholfen.

Grüße
Highchiller
 

X5-599

Top Contributor
Danke für die Blumen :)

Keine Ahnung, ob das ein Moderator verschieben (kopieren) möchte...

Ja, das Look And Feel bleibt erhalten. Bloss das Vorgehen des Zeichnens des Strings ist jetzt immer gleich. Normalerweise macht das ja jedes Look And Feel auf seine Weise. Evtl könnte man ja einen Schalter einbauen, der das Zeichnen bei Bedarf wieder auf "alte" Weise macht.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
R LookAndFeel Wie kann man die Textfarbe der Nimbus ProgressBar nach Füllstand ändern? AWT, Swing, JavaFX & SWT 2
M JTabbedPane verändern mit Nimbus Look and Feel AWT, Swing, JavaFX & SWT 1
V LookAndFeel JSpinner Hintergrund Farbe mit Nimbus LaF AWT, Swing, JavaFX & SWT 0
H Nimbus L&F TitledBorder AWT, Swing, JavaFX & SWT 2
V Nimbus Look and Feel register Region problem AWT, Swing, JavaFX & SWT 5
V Nimbus Look And Feel Button textForeground AWT, Swing, JavaFX & SWT 8
M jTabbedPain und Nimbus AWT, Swing, JavaFX & SWT 4
T Nimbus JButton: Zeilenumbruch korrigieren? AWT, Swing, JavaFX & SWT 9
N Nimbus Look & Feel AWT, Swing, JavaFX & SWT 4
hdi LookAndFeel Nimbus BUG mit JTabbedPane?! AWT, Swing, JavaFX & SWT 5
Y LookAndFeel Nimbus einschalten geht nicht AWT, Swing, JavaFX & SWT 31
V Swing Nimbus Look And Feel verschiedene Buttons AWT, Swing, JavaFX & SWT 8
A LookAndFeel Rollover Effekt bei JTabbedPane deaktivieren (Nimbus) AWT, Swing, JavaFX & SWT 8
B LookAndFeel Cell Renderer für JTable bei Nimbus Look and Feel AWT, Swing, JavaFX & SWT 2
T Nimbus Überschrift AWT, Swing, JavaFX & SWT 10
P LookAndFeel nimbus JLabel undurchsichtig opaque funktioniert nicht AWT, Swing, JavaFX & SWT 4
R LookAndFeel Nimbus ändert Programmausführung AWT, Swing, JavaFX & SWT 8
Y LookAndFeel JTabbedPane: Tab-Farbe mit Nimbus setzen AWT, Swing, JavaFX & SWT 3
N Swing Nimbus arbeitet nicht korrekt korrekt bei setEnabled() für JMenuItem AWT, Swing, JavaFX & SWT 2
C LookAndFeel Nimbus TabbedPane Backgroundcolor AWT, Swing, JavaFX & SWT 12
S Metal-Buttons so aussehen lassen wie Nimbus Buttons? AWT, Swing, JavaFX & SWT 3
Fu3L Keine Transparenten JTextComponents möglich mit Nimbus L&F? AWT, Swing, JavaFX & SWT 5
S Swing JTable in Nimbus AWT, Swing, JavaFX & SWT 4
O nimbus Abbrechen ok vertauscht AWT, Swing, JavaFX & SWT 2
E Look & Feel - Nimbus AWT, Swing, JavaFX & SWT 12
A Nimbus eigener Painter funzt nicht AWT, Swing, JavaFX & SWT 11
data89 Nimbus Look and Feel als gepackte JAR-Datei AWT, Swing, JavaFX & SWT 3
T Swing: TaskPane mit Nimbus LnF? AWT, Swing, JavaFX & SWT 4
M Problem Nimbus Look&Feel AWT, Swing, JavaFX & SWT 2
oliver1974 Nimbus Look & Feel und die Ausgaben nach Standardaus. AWT, Swing, JavaFX & SWT 4
F Progressbar Farbe AWT, Swing, JavaFX & SWT 6
T Swing Reload JPanel + darin liegende ProgressBar AWT, Swing, JavaFX & SWT 9
A Swing ProgressBar über 2 parallel laufende Threads AWT, Swing, JavaFX & SWT 2
P JavaFx - Progressbar - Füllen mittels mehreren Tasks AWT, Swing, JavaFX & SWT 0
Bluedaishi JavaFX ProgressBar AWT, Swing, JavaFX & SWT 10
T Starten des Programms mit dem Progressbar AWT, Swing, JavaFX & SWT 2
L Progressbar Laufzeitveränderung AWT, Swing, JavaFX & SWT 4
1 Swing Progressbar benutzen um Fortschritt einer Methode anzuzeigen AWT, Swing, JavaFX & SWT 4
B JavaFX Textfields: Fortschritt als ProgressBar und Progressindicator AWT, Swing, JavaFX & SWT 5
MR._FIRE_Flower progressBar in ein bestehendes Programm einbauen AWT, Swing, JavaFX & SWT 3
M Wie binde ich eine JavaFX ProgressBar an eine Datei Übertragung? AWT, Swing, JavaFX & SWT 2
Z Swing Swing und die Progressbar AWT, Swing, JavaFX & SWT 1
I JavaFX Im Controller die ProgressBar mit Task updaten AWT, Swing, JavaFX & SWT 6
M JavaFX Progressbar bar und track Komponente zur Laufzeit ändern AWT, Swing, JavaFX & SWT 2
Z ProgressBar in Eclipse mit Wizard page? AWT, Swing, JavaFX & SWT 1
W Swing ProgressBar update AWT, Swing, JavaFX & SWT 4
A JavaFX Eine Task mit einer ProgressBar verbinden AWT, Swing, JavaFX & SWT 0
P Swing Die ProgressBar wird nicht angezeigt AWT, Swing, JavaFX & SWT 5
B SWT Progressbar mit Textoverlay? AWT, Swing, JavaFX & SWT 3
M ProgressBar in ActionListener AWT, Swing, JavaFX & SWT 4
T Prozessstatus in Progressbar anzeigen AWT, Swing, JavaFX & SWT 5
J Swing Progressbar aktualisiert sich nicht AWT, Swing, JavaFX & SWT 17
V Persistentes Objekt laden Progressbar AWT, Swing, JavaFX & SWT 7
V Swing Progressbar Problem AWT, Swing, JavaFX & SWT 14
B ProgressBar während Berechnung AWT, Swing, JavaFX & SWT 4
Tobse LookAndFeel [Windows7] Nativ aussehnde ProgressBar AWT, Swing, JavaFX & SWT 13
J Progressbar mit einfacher Funktion AWT, Swing, JavaFX & SWT 6
D Progressbar AWT, Swing, JavaFX & SWT 5
H Zeile in DefaultTableModel hinzufügen, ProgressBar AWT, Swing, JavaFX & SWT 4
S Upload Progressbar AWT, Swing, JavaFX & SWT 3
S Dateien kopieren mit ProgressBar AWT, Swing, JavaFX & SWT 6
S Swing ProgressBar AWT, Swing, JavaFX & SWT 3
S SWT ProgressBar: Value/Selection anzeigen AWT, Swing, JavaFX & SWT 4
D SWT JFace Wizard Progressbar AWT, Swing, JavaFX & SWT 4
S ProgressBar newRunnable (schon wieder!) AWT, Swing, JavaFX & SWT 9
ModellbahnerTT Progressbar anzeigen AWT, Swing, JavaFX & SWT 5
J Progressbar aktualisierung nach file übergabe AWT, Swing, JavaFX & SWT 7
P Progressbar in java AWT, Swing, JavaFX & SWT 3
K Frage zu ProgressBar, SwingWorker etc. AWT, Swing, JavaFX & SWT 4
V ProgressBar AWT, Swing, JavaFX & SWT 5
D Suche verticale Progressbar AWT, Swing, JavaFX & SWT 2
M Bug; Swing-Worker, Progressbar und Mouse AWT, Swing, JavaFX & SWT 22
P [SWT] - ProgressBar, Prozentzahlen live anzeigen geht nicht AWT, Swing, JavaFX & SWT 13
P JTable sortiert ProgressBar nicht AWT, Swing, JavaFX & SWT 8
L Button ändert eigenes Bild und Progressbar-Value nicht AWT, Swing, JavaFX & SWT 6
B Eine Alternative zur Steuerung einer ProgressBar? AWT, Swing, JavaFX & SWT 5
N ProgressBar --> brauche Hilfe AWT, Swing, JavaFX & SWT 4
G Progressbar aktualisiert sich nicht (vernünftig). WIESO? AWT, Swing, JavaFX & SWT 2
S Anzeige einer Progressbar. AWT, Swing, JavaFX & SWT 3
M Bild laden + ProgressBar AWT, Swing, JavaFX & SWT 2
C Problem mit ProgressBar AWT, Swing, JavaFX & SWT 4
thE_29 Problem mit ProgressBar AWT, Swing, JavaFX & SWT 2
M ProgressBar in einem Thread? AWT, Swing, JavaFX & SWT 4
C ProgressBar AWT, Swing, JavaFX & SWT 4
J JavaFX Stacked Bar Chart - XYChart.Series Colors AWT, Swing, JavaFX & SWT 0
H Liste von Font Sizes und Colors AWT, Swing, JavaFX & SWT 4

Ähnliche Java Themen


Oben