Skip to content

Commit 8583b87

Browse files
authored
Merge pull request #976 from knowm/timmolter-fix-975-chart-button-styling
Fix #975: move chart button styling out of Styler/Theme into ChartButtonConfig
2 parents 911114b + 160bb72 commit 8583b87

8 files changed

Lines changed: 307 additions & 160 deletions

File tree

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package org.knowm.xchart.standalone.issues;
2+
3+
import org.knowm.xchart.ChartButtonConfig;
4+
import org.knowm.xchart.ChartButtonConfig.ChartButtonPosition;
5+
import org.knowm.xchart.SwingWrapper;
6+
import org.knowm.xchart.XChartPanel;
7+
import org.knowm.xchart.XYChart;
8+
import org.knowm.xchart.XYChartBuilder;
9+
import org.knowm.xchart.style.colors.ChartColor;
10+
11+
/**
12+
* Demonstrates issue #975 — chart button styling moved out of {@code Styler}/{@code Theme} into
13+
* {@link ChartButtonConfig} on {@link XChartPanel}.
14+
*
15+
* <p>Previously, {@code Styler} carried six {@code chartButton*} fields that were exclusively used
16+
* by the Swing layer ({@code ChartButton}, {@code ChartZoom}), polluting every headless render
17+
* path. These have been removed from {@code Styler} and {@code Theme} and replaced by the new
18+
* {@link ChartButtonConfig} class, which lives entirely within the Swing rendering layer.
19+
*
20+
* <p>This demo shows the zoom-reset button using a custom {@code ChartButtonConfig}: red
21+
* background, white text, and positioned in the bottom-right corner. Drag a selection on the chart
22+
* to trigger the zoom and reveal the styled reset button.
23+
*/
24+
public class TestForIssue975 {
25+
26+
public static void main(String[] args) {
27+
28+
SwingWrapper<XYChart> sw = new SwingWrapper<>(getChart());
29+
sw.displayChart();
30+
31+
// Configure zoom and the custom button style on the panel created by SwingWrapper.
32+
sw.getXChartPanel()
33+
.setChartButtonConfig(
34+
new ChartButtonConfig()
35+
.setBackgroundColor(ChartColor.RED.getColor())
36+
.setBorderColor(ChartColor.DARK_GREY.getColor())
37+
.setFontColor(java.awt.Color.WHITE)
38+
.setMargin(8)
39+
.setPosition(ChartButtonPosition.InsideSE))
40+
.setZoomEnabled(true)
41+
.setZoomResetByButton(true);
42+
}
43+
44+
/** Constructs and returns the chart without launching a window (headless-safe). */
45+
public static XYChart getChart() {
46+
47+
XYChart chart =
48+
new XYChartBuilder()
49+
.width(700)
50+
.height(400)
51+
.title("Issue #975 – ChartButtonConfig demo")
52+
.xAxisTitle("X")
53+
.yAxisTitle("Y")
54+
.build();
55+
56+
chart.addSeries("series1", new double[]{1, 2, 3, 4, 5}, new double[]{2, 4, 3, 7, 5});
57+
chart.addSeries("series2", new double[]{1, 2, 3, 4, 5}, new double[]{5, 3, 6, 2, 8});
58+
return chart;
59+
}
60+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package org.knowm.xchart;
2+
3+
import java.awt.Color;
4+
import java.awt.Font;
5+
import org.knowm.xchart.style.colors.ChartColor;
6+
7+
/**
8+
* Holds all styling configuration for the chart zoom-reset button rendered inside {@link
9+
* XChartPanel}. Keeping these Swing-only concerns here prevents them from polluting the
10+
* renderer-agnostic {@code Styler} / {@code Theme} layer.
11+
*/
12+
public class ChartButtonConfig {
13+
14+
/** Position of the button within the chart plot area. */
15+
public enum ChartButtonPosition {
16+
InsideNW,
17+
InsideNE,
18+
InsideSE,
19+
InsideSW,
20+
InsideN,
21+
InsideS
22+
}
23+
24+
private Color backgroundColor = ChartColor.LIGHT_GREY.getColor();
25+
private Color borderColor = ChartColor.DARK_GREY.getColor();
26+
private Color fontColor = ChartColor.BLACK.getColor();
27+
private Font font = new Font(Font.SANS_SERIF, Font.PLAIN, 11);
28+
private int margin = 6;
29+
private ChartButtonPosition position = ChartButtonPosition.InsideN;
30+
31+
public Color getBackgroundColor() {
32+
33+
return backgroundColor;
34+
}
35+
36+
/**
37+
* Sets the button background color.
38+
*
39+
* @param backgroundColor the background color
40+
*/
41+
public ChartButtonConfig setBackgroundColor(Color backgroundColor) {
42+
43+
this.backgroundColor = backgroundColor;
44+
return this;
45+
}
46+
47+
public Color getBorderColor() {
48+
49+
return borderColor;
50+
}
51+
52+
/**
53+
* Sets the button border color.
54+
*
55+
* @param borderColor the border color
56+
*/
57+
public ChartButtonConfig setBorderColor(Color borderColor) {
58+
59+
this.borderColor = borderColor;
60+
return this;
61+
}
62+
63+
public Color getFontColor() {
64+
65+
return fontColor;
66+
}
67+
68+
/**
69+
* Sets the button label font color.
70+
*
71+
* @param fontColor the font color
72+
*/
73+
public ChartButtonConfig setFontColor(Color fontColor) {
74+
75+
this.fontColor = fontColor;
76+
return this;
77+
}
78+
79+
public Font getFont() {
80+
81+
return font;
82+
}
83+
84+
/**
85+
* Sets the button label font.
86+
*
87+
* @param font the font
88+
*/
89+
public ChartButtonConfig setFont(Font font) {
90+
91+
this.font = font;
92+
return this;
93+
}
94+
95+
public int getMargin() {
96+
97+
return margin;
98+
}
99+
100+
/**
101+
* Sets the padding around the button label, in pixels.
102+
*
103+
* @param margin the margin
104+
*/
105+
public ChartButtonConfig setMargin(int margin) {
106+
107+
this.margin = margin;
108+
return this;
109+
}
110+
111+
public ChartButtonPosition getPosition() {
112+
113+
return position;
114+
}
115+
116+
/**
117+
* Sets the position of the button within the chart plot area.
118+
*
119+
* @param position the position
120+
*/
121+
public ChartButtonConfig setPosition(ChartButtonPosition position) {
122+
123+
this.position = position;
124+
return this;
125+
}
126+
}

xchart/src/main/java/org/knowm/xchart/XChartPanel.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.awt.print.PrinterJob;
2020
import java.io.File;
2121
import java.io.IOException;
22+
import java.util.Objects;
2223

2324
import javax.swing.AbstractAction;
2425
import javax.swing.JFileChooser;
@@ -38,6 +39,7 @@
3839
import org.knowm.xchart.internal.chartpart.ChartZoom;
3940
import org.knowm.xchart.internal.chartpart.Cursor;
4041
import org.knowm.xchart.internal.chartpart.ToolTips;
42+
import org.knowm.xchart.style.Styler;
4143

4244
/**
4345
* A Swing JPanel that contains a Chart
@@ -62,6 +64,7 @@ public class XChartPanel<T extends Chart<?, ?>> extends JPanel {
6264
private boolean zoomResetByDoubleClick = true;
6365
private boolean zoomResetByButton = true;
6466
private boolean cursorEnabled = false;
67+
private ChartButtonConfig chartButtonConfig;
6568

6669
/**
6770
* Constructor
@@ -73,6 +76,12 @@ public XChartPanel(final T chart) {
7376
this.chart = chart;
7477
preferredSize = new Dimension(chart.getWidth(), chart.getHeight());
7578

79+
Styler styler = chart.getStyler();
80+
chartButtonConfig =
81+
new ChartButtonConfig()
82+
.setFontColor(styler.getChartFontColor())
83+
.setFont(styler.getBaseFont().deriveFont(11f));
84+
7685
// Right-click listener for saving chart
7786
this.addMouseListener(new PopUpMenuClickListener());
7887

@@ -203,6 +212,25 @@ public boolean isZoomResetByDoubleClick() {
203212
return zoomResetByDoubleClick;
204213
}
205214

215+
public ChartButtonConfig getChartButtonConfig() {
216+
217+
return chartButtonConfig;
218+
}
219+
220+
/**
221+
* Replaces the default {@link ChartButtonConfig} for the zoom-reset button. If zoom has already
222+
* been enabled, interactions are rewired so the new config takes effect immediately.
223+
*
224+
* @param chartButtonConfig the new config (must not be null)
225+
*/
226+
public XChartPanel<T> setChartButtonConfig(ChartButtonConfig chartButtonConfig) {
227+
228+
Objects.requireNonNull(chartButtonConfig, "chartButtonConfig must not be null");
229+
this.chartButtonConfig = chartButtonConfig;
230+
rewireInteractions();
231+
return this;
232+
}
233+
206234
private void rewireInteractions() {
207235

208236
if (toolTips != null) {

0 commit comments

Comments
 (0)