我在JavaFX
中使用Swing
,因此我对此JFrame
和JFXPanel
。 StackPane
上有JPanel
的场景。
框架上还有菜单,它与面板连接。
如何按菜单项重新绘制面板或堆栈窗格? (我想更改字体或其他点击的内容,例如,查看 - 电子格式,但任何事情都不会发生)
我知道JavaFX中没有模拟repaint()
,因此我该怎么办呢?
在mainClass中查看 set_formatType ,在StackChart中查看 yAxis格式
MCVE:
mainClass.java
public abstract class mainClass extends Application {
public static final int X_NUMBER = 20;
static StackChart chart;
// --- MENU
static JMenuBar mainMenuBar;
static JMenuBar menuBar;
static JMenu menuFile;
static JMenu menuView;
JMenu menuAbout;
JMenu menuFontSize;
JMenu menuFont;
JMenuItem menuItem;
JRadioButtonMenuItem rbMenuItem;
JCheckBoxMenuItem cbMenuItem;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
initAndShowGUI();
}
});
}
private static void initAndShowGUI() {
// This method is invoked on Swing thread
JFrame frame = new JFrame("FX");
final JFXPanel fxPanel = new JFXPanel();
frame.add(fxPanel);
frame.setVisible(true);
frame.setSize((int)Toolkit.getDefaultToolkit().getScreenSize().getWidth(), (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight());
mainMenuBar = createMenu();
frame.setJMenuBar(mainMenuBar);
Platform.runLater(new Runnable() {
@Override
public void run() {
initFX(fxPanel);
}
});
}
private static void initFX(JFXPanel fxPanel) {
// This method is invoked on JavaFX thread
Scene scene = createScene();
fxPanel.setScene(scene);
}
private static Scene createScene() {
Group root = new Group();
Scene scene = new Scene(root, 1024, 600);
BorderPane borderPane = new BorderPane();
NumberAxis xAxis = new NumberAxis();
NumberAxis yAxis = new NumberAxis();
yAxis.setLabel("Scale 1");
LineChart baseChart = new LineChart(xAxis, yAxis);
baseChart.getData().add(prepareSeries("Serie 1", (x) -> (double) x));
chart = new StackChart(baseChart, Color.RED);
chart.addSeries(prepareSeries("Serie 2", (x) -> (double) -2*x * x), Color.BLUE);
borderPane.setCenter(chart);
borderPane.setPrefSize(800, 600);
borderPane.setBottom(chart.getLegend());
root.getChildren().add(borderPane);
return scene;
}
private static XYChart.Series<Number, Number> prepareSeries(String name, Function<Integer, Double> function) {
XYChart.Series<Number, Number> series = new XYChart.Series<>();
series.setName(name);
for (int i = 0; i < X_NUMBER; i++) {
series.getData().add(new XYChart.Data<>(i, function.apply(i)));
}
return series;
}
public static JMenuBar createMenu() {
menuBar = new JMenuBar();
// --- VIEW
menuView = new JMenu("View");
menuView.setMnemonic(KeyEvent.VK_V);
JMenuItem axisFormat = new JMenuItem("E-format");
axisFormat.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
chart.set_formatType(2);
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
});
menuView.add(axisFormat);
menuBar.add(menuView);
return menuBar;
}
}
StackChart.java
public class StackChart extends StackPane {
private final LineChart baseChart;
private final ObservableList<LineChart> backCharts = FXCollections.observableArrayList();
private final double yAxisWidth = 60;
private final AnchorPane details;
private final double yAxisSeparation = 20;
private double strokeWidth = 0.3;
public int _formatType = 1;
public StackChart(LineChart baseChart, Color lineColor) {
this(baseChart, lineColor, null);
}
public StackChart(LineChart baseChart, Color lineColor, Double strokeWidth) {
if (strokeWidth != null) {
this.strokeWidth = strokeWidth;
}
this.baseChart = baseChart;
baseChart.setCreateSymbols(false);
baseChart.setLegendVisible(false);
baseChart.getXAxis().setAutoRanging(false);
baseChart.getXAxis().setAnimated(false);
baseChart.getXAxis().setStyle("-fx-font-size:" + 18);
baseChart.getYAxis().setAnimated(false);
baseChart.getYAxis().setStyle("-fx-font-size:" + 18);
setStyle(baseChart, lineColor);
setFixedAxisWidth(baseChart);
setAlignment(Pos.CENTER_LEFT);
backCharts.addListener((Observable observable) -> rebuildChart());
details = new AnchorPane();
bindMouseEvents(baseChart, this.strokeWidth);
rebuildChart();
}
private void bindMouseEvents(LineChart baseChart, Double strokeWidth) {
getChildren().add(details);
details.prefHeightProperty().bind(heightProperty());
details.prefWidthProperty().bind(widthProperty());
details.setMouseTransparent(true);
setOnMouseMoved(null);
setMouseTransparent(false);
final Axis xAxis = baseChart.getXAxis();
final Axis yAxis = baseChart.getYAxis();
final Line xLine = new Line();
final Line yLine = new Line();
yLine.setFill(Color.GRAY);
xLine.setFill(Color.GRAY);
yLine.setStrokeWidth(strokeWidth/2);
xLine.setStrokeWidth(strokeWidth/2);
xLine.setVisible(false);
yLine.setVisible(false);
final Node chartBackground = baseChart.lookup(".chart-plot-background");
for (Node n: chartBackground.getParent().getChildrenUnmodifiable()) {
if (n != chartBackground && n != xAxis && n != yAxis) {
n.setMouseTransparent(true);
}
}
chartBackground.setCursor(Cursor.CROSSHAIR);
chartBackground.setOnMouseEntered((event) -> {
chartBackground.getOnMouseMoved().handle(event);
xLine.setVisible(true);
yLine.setVisible(true);
details.getChildren().addAll(xLine, yLine);
});
chartBackground.setOnMouseExited((event) -> {
xLine.setVisible(false);
yLine.setVisible(false);
details.getChildren().removeAll(xLine, yLine);
});
chartBackground.setOnMouseMoved(event -> {
double x = event.getX() + chartBackground.getLayoutX();
double y = event.getY() + chartBackground.getLayoutY();
xLine.setStartX(65);
xLine.setEndX(details.getWidth()-10);
xLine.setStartY(y+5);
xLine.setEndY(y+5);
yLine.setStartX(x+5);
yLine.setEndX(x+5);
yLine.setStartY(12);
yLine.setEndY(details.getHeight()-28);
});
}
private void setFixedAxisWidth(LineChart chart) {
chart.getYAxis().setPrefWidth(yAxisWidth);
chart.getYAxis().setMaxWidth(yAxisWidth);
}
private void rebuildChart() {
getChildren().clear();
getChildren().add(resizeBaseChart(baseChart));
for (LineChart lineChart : backCharts) {
getChildren().add(resizeBackgroundChart(lineChart));
}
getChildren().add(details);
}
private Node resizeBaseChart(LineChart lineChart) {
HBox hBox = new HBox(lineChart);
hBox.setAlignment(Pos.CENTER_LEFT);
hBox.prefHeightProperty().bind(heightProperty());
hBox.prefWidthProperty().bind(widthProperty());
lineChart.minWidthProperty().bind(widthProperty().subtract((yAxisWidth+yAxisSeparation)*backCharts.size()));
lineChart.prefWidthProperty().bind(widthProperty().subtract((yAxisWidth+yAxisSeparation)*backCharts.size()));
lineChart.maxWidthProperty().bind(widthProperty().subtract((yAxisWidth+yAxisSeparation)*backCharts.size()));
return lineChart;
}
private Node resizeBackgroundChart(LineChart lineChart) {
HBox hBox = new HBox(lineChart);
hBox.setAlignment(Pos.CENTER_LEFT);
hBox.prefHeightProperty().bind(heightProperty());
hBox.prefWidthProperty().bind(widthProperty());
hBox.setMouseTransparent(true);
lineChart.minWidthProperty().bind(widthProperty().subtract((yAxisWidth + yAxisSeparation) * backCharts.size()));
lineChart.prefWidthProperty().bind(widthProperty().subtract((yAxisWidth + yAxisSeparation) * backCharts.size()));
lineChart.maxWidthProperty().bind(widthProperty().subtract((yAxisWidth + yAxisSeparation) * backCharts.size()));
lineChart.translateXProperty().bind(baseChart.getYAxis().widthProperty());
lineChart.getYAxis().setTranslateX((yAxisWidth + yAxisSeparation) * backCharts.indexOf(lineChart));
return hBox;
}
public void addSeries(XYChart.Series series, Color lineColor) {
NumberAxis yAxis = new NumberAxis();
NumberAxis xAxis = new NumberAxis();
// xAxis
xAxis.setAutoRanging(false);
xAxis.setVisible(false);
xAxis.setOpacity(0.0);
xAxis.lowerBoundProperty().bind(((NumberAxis) baseChart.getXAxis()).lowerBoundProperty());
xAxis.upperBoundProperty().bind(((NumberAxis) baseChart.getXAxis()).upperBoundProperty());
xAxis.tickUnitProperty().bind(((NumberAxis) baseChart.getXAxis()).tickUnitProperty());
// yAxis
yAxis.setSide(Side.RIGHT);
yAxis.setLabel(series.getName());
if(_formatType == 2){
NumberFormat format = new DecimalFormat("#.#E0");
yAxis.setTickLabelFormatter(new StringConverter<Number>() {
@Override
public String toString(Number number) {
return format.format(number.doubleValue());
}
@Override
public Number fromString(String string) {
try {
return format.parse(string);
} catch (ParseException e) {
e.printStackTrace();
return 0 ;
}
}
});
}
// create chart
LineChart lineChart = new LineChart(xAxis, yAxis);
lineChart.setAnimated(false);
lineChart.setLegendVisible(false);
lineChart.getData().add(series);
styleBackChart(lineChart, lineColor);
setFixedAxisWidth(lineChart);
backCharts.add(lineChart);
}
private void styleBackChart(LineChart lineChart, Color lineColor) {
setStyle(lineChart, lineColor);
Node contentBackground = lineChart.lookup(".chart-content").lookup(".chart-plot-background");
contentBackground.setStyle("-fx-background-color: transparent;");
lineChart.setVerticalZeroLineVisible(false);
lineChart.setHorizontalZeroLineVisible(false);
lineChart.setVerticalGridLinesVisible(false);
lineChart.setHorizontalGridLinesVisible(false);
lineChart.setCreateSymbols(false);
lineChart.getXAxis().setStyle("-fx-font-size:" + 18);
lineChart.getYAxis().setStyle("-fx-font-size:" + 18);
}
private String toRGBCode(Color color) {
return String.format("#%02X%02X%02X",
(int) (color.getRed() * 255),
(int) (color.getGreen() * 255),
(int) (color.getBlue() * 255));
}
private void setStyle(LineChart chart, Color lineColor) {
chart.getYAxis().lookup(".axis-label").setStyle("-fx-text-fill: " + toRGBCode(lineColor) + "; -fx-font-size: 24;");
Node seriesLine = chart.lookup(".chart-series-line");
seriesLine.setStyle("-fx-stroke: " + toRGBCode(lineColor) + "; -fx-stroke-width: " + strokeWidth + ";");
}
public Node getLegend() {
HBox hbox = new HBox();
final CheckBox baseChartCheckBox = new CheckBox(baseChart.getYAxis().getLabel());
baseChartCheckBox.setSelected(true);
baseChartCheckBox.setDisable(true);
baseChartCheckBox.getStyleClass().add("readonly-checkbox");
baseChartCheckBox.setOnAction(event -> baseChartCheckBox.setSelected(true));
hbox.getChildren().add(baseChartCheckBox);
for (final LineChart lineChart : backCharts) {
CheckBox checkBox = new CheckBox(lineChart.getYAxis().getLabel());
checkBox.setSelected(true);
checkBox.setOnAction(event -> {
if (backCharts.contains(lineChart)) {
backCharts.remove(lineChart);
} else {
backCharts.add(lineChart);
}
});
hbox.getChildren().add(checkBox);
}
hbox.setAlignment(Pos.CENTER);
hbox.setSpacing(20);
hbox.setStyle("-fx-padding: 0 10 20 10");
return hbox;
}
public int is_formatType() {
return _formatType;
}
public void set_formatType(int formatType) {
this._formatType = formatType;
this.requestLayout();
}
}
答案 0 :(得分:0)
问题可能是这段代码
chart.set_formatType(2);
尝试修改Swing线程上的JavaFX节点。这可能会解决它:
Platform.runLater(new Runnable() {
@Override
public void run() {
chart.set_formatType(2);
}
});
中介绍了这一点
此外,您的set_formatType
方法无法执行任何操作。您更改了自己的一个属性并调用requestLayout
,这不会按照您希望的方式执行。您需要更改图表的其中一个属性。这将触发“重新粉刷”。