-1

负责创建一个用户界面,该界面具有一个包含菜单的顶栏。菜单应该有四个项目。首先将日期打印到对话框中,第二次将该日期写入 .txt 文件,第三次将框架背景颜色更改为绿色的随机色调,第四次退出。

除了 3 号之外,我的所有功能都正常工作。我已对其进行了设置,以便在您选择 colorItem MenuItem 时,menuBar 变为预定的绿色。

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import java.util.Random;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import java.time.LocalDate;


public class Main extends Application {
    @Override
    public void start(Stage stage) {
 
        // Create MenuBar
        MenuBar menuBar = new MenuBar();
        
        // Create menus
        Menu dateMenu = new Menu("Print");
        Menu textMenu = new Menu("Write");
        Menu colorMenu = new Menu("Change Color");
        Menu exitMenu = new Menu("Options");
        
        // Create MenuItems
        MenuItem dateItem = new MenuItem("Date/Time");
        MenuItem textItem = new MenuItem("Save To Text File");
        MenuItem colorItem = new MenuItem("Random Color");
        MenuItem exitItem = new MenuItem("Exit");
        
        // Add menuItems to the Menus
        dateMenu.getItems().addAll(dateItem);
        textMenu.getItems().addAll(textItem);
        colorMenu.getItems().addAll(colorItem);
        exitMenu.getItems().addAll(exitItem);
        
        // Add Menus to the MenuBar
        menuBar.getMenus().addAll(dateMenu, textMenu, colorMenu, exitMenu);
        
       
        // When user clicks on Date/Time MenuItem
        dateMenu.setOnAction(new EventHandler<ActionEvent>()    {

            @Override
            public void handle(ActionEvent event) {
                LocalDate today = LocalDate.now();
                Alert alert = new Alert(AlertType.INFORMATION);
                alert.setTitle("Date Printer");
                alert.setHeaderText(null);
                alert.setContentText("Today's Date is: " + today);
                alert.showAndWait();
                            }
        });
        
        // When user clicks on Save to Text File MenuItem
        textMenu.setOnAction(new EventHandler<ActionEvent>()    {

            @Override
            public void handle(ActionEvent event) {
                LocalDate today = LocalDate.now();
                try {
                    
                    // Log message created
                    String content = "Button clicked on: " + today;

                    File file = new  File("C:\\Users\\stca\\OneDrive - Episerver\\Desktop\\Week3.txt");

                    // File already created on desktop
                    if (!file.exists()) {
                        file.createNewFile();
                    }

                    FileWriter fw = new FileWriter(file.getAbsoluteFile());
                    BufferedWriter bw = new BufferedWriter(fw);
                    bw.write(content);
                    bw.close();

                    System.out.println("Done");

                } catch (IOException e) {
                    e.printStackTrace();
                }
                            }
        });
        
        // When user clicks on Change Color MenuItem
        colorMenu.setOnAction(new EventHandler<ActionEvent>()   {

            @Override
            public void handle(ActionEvent event) {
                menuBar.setStyle("-fx-background-color: #33cc33;");
                            }
        });
        
        // Set Accelerator for Exit MenuItem.
        exitItem.setAccelerator(KeyCombination.keyCombination("Ctrl+X"));
         
        // When user clicks on the Exit MenuItem
        exitItem.setOnAction((EventHandler<ActionEvent>) new EventHandler<ActionEvent>() {
         
            @Override
            public void handle(ActionEvent event) {
                System.exit(0);
            }
        });
        

        BorderPane root = new BorderPane();
        root.setTop(menuBar);
        Scene scene = new Scene(root, 400, 200);
        
        stage.setTitle("JavaFX Menu for CSC372");
        stage.setScene(scene);
        stage.show();
    }
 
    public static void main(String[] args) {
        Application.launch(args);
    }
 
}

如何让背景改变颜色而不是 menuBar?另外,我怎样才能调用不同色调的绿色随机化?我试过这个:

        // When user clicks on Change Color MenuItem
        colorMenu.setOnAction(new EventHandler<ActionEvent>()   {

            @Override
            public void handle(ActionEvent event) {
                Random random = new Random(); 
                int r = random.nextInt(); 
                int g = random.nextInt(); 
                int b = random.nextInt(); 
                Color randomColor = new Color(r, g, b);
                menuBar.setStyle("-fx-background-color: randomColor");
                            }
        });

但是我的 IDE 告诉我构造函数不可见。

4

1 回答 1

1

示例代码

此代码允许用户在选择菜单项后触发设置随机背景颜色(绿色阴影)。

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import java.util.Random;

public class ColorSelector extends Application {
    private final Random random = new Random(42);

    private final ColorGenerator colorGenerator = new ColorGenerator();

    @Override
    public void start(Stage stage) {
        MenuItem colorItem = new MenuItem("Random Color");
        Menu colorMenu = new Menu("Change Color", null, colorItem);
        MenuBar menuBar = new MenuBar(colorMenu);

        BorderPane root = new BorderPane();
        root.setTop(menuBar);
        setRandomBackgroundColor(root);
        colorMenu.setOnAction(event -> setRandomBackgroundColor(root));

        Scene scene = new Scene(root, 400, 200);
        stage.setScene(scene);

        stage.show();
    }

    private void setRandomBackgroundColor(Region region) {
        Color color = colorGenerator.generateRandomShadeOfGreen();

        // option 1: set the fill on the root via a background color.
        region.setBackground(
                new Background(
                        new BackgroundFill(color, null, null)
                )
        );

        // option 2: set the fill on the root via a css style.
        // region.setStyle("-fx-background-color: #" + colorToString(color));
    }

    private String colorToString(Color color) {
        int r = (int)Math.round(color.getRed() * 255.0);
        int g = (int)Math.round(color.getGreen() * 255.0);
        int b = (int)Math.round(color.getBlue() * 255.0);
        int o = (int)Math.round(color.getOpacity() * 255.0);

        return String.format("%02x%02x%02x%02x" , r, g, b, o);
    }

    public static void main(String[] args) {
        Application.launch(args);
    }

    private class ColorGenerator {
        private int curColorIndex = 0;

        private final Color[] colorTable = {
                Color.rgb(0, 50, 0),
                Color.rgb(0, 100, 0),
                Color.rgb(0, 150, 0),
                Color.rgb(0, 250, 0),
        };

        private Color generateRandomShadeOfGreen() {
            int nextColorIndex = curColorIndex;

            while (nextColorIndex == curColorIndex) {
                nextColorIndex = random.nextInt(colorTable.length);
            }

            curColorIndex = nextColorIndex;

            return colorTable[nextColorIndex];
        }
    }
}

关于使用此解决方案的建议

我知道这是你的作业,但无论如何这里有一个示例解决方案,我不建议只是复制并粘贴它并提交它,如果遇到问题,你可以使用它来检查你的实现。

为了获得奖励积分,请尝试理解Random(42)(阅读 javadoc for Random)的含义。此外,请阅读 JavaFX CSS 参考指南的相关API javadoc 和Background颜色部分Color

实施说明

对于颜色查找,它使用预定义的颜色表,在我看来这是一个很好的解决问题的方法。

该表可以在 CSS 外部而不是内联中定义,这样做超出了此答案的范围。如果有兴趣,请在 JavaFX 源代码库中搜索文件中 CHART_COLOR_ 的用法,moderna.css看看它是如何完成的。

如果需要,您可以为 RGB 说明符创建一个随机 g 值,而不是使用查找表。

该代码演示了通过BackgroundFill内联 CSS 样式或内联 CSS 样式设置颜色。

颜色随机化功能的其他问题

  1. 参数(即使对于正确的颜色构造函数)将具有 RGB 值范围(例如 0-255),因此您不能只使用任何随机 int 值。
  2. 您可能不想要太低的 RGB 值,否则肉眼看起来只是黑色。
  3. 您不能只获取一个 Java 变量并将其名称写入字符串以在字符串中包含变量值。
  4. 如果您只想要绿色 RGB 颜色,则将 r 和 b 值设置为 0。
  5. 重用随机数生成器,不要每次点击都创建一个,那很昂贵。
于 2021-09-03T00:28:53.597 回答