2012-06-20 30 views
11

Tôi đang cố thay đổi kiểu của một mục ContextMenu bằng cách sử dụng tệp CSS riêng biệt. Tôi nhìn phần caspian.css và tìm thấy các định nghĩa sau đây:Làm thế nào để bạn đặt phong cách cho một JavaFX ContextMenu bằng cách sử dụng css?

  • .context menu
  • .context menu .separator
  • .context menu .scroll-mũi tên
  • .context- đơn .scroll mũi tên: di chuột
  • .context-menu: show-mnemonics .mnemonic-gạch dưới

tôi sao chép những người trên chính xác đến file css của tôi và thay đổi chỉ là màu nền các giá trị dưới dạng thử nghiệm:

.context-menu { 
    -fx-skin: "com.sun.javafx.scene.control.skin.ContextMenuSkin"; 
    -fx-background-color: #006699; 
    -fx-background-insets: 0, 1, 2; 
    -fx-background-radius: 0 6 6 6, 0 5 5 5, 0 4 4 4; 
/* -fx-padding: 0.666667em 0.083333em 0.666667em 0.083333em; 8 1 8 1 */ 
    -fx-padding: 0.333333em 0.083333em 0.666667em 0.083333em; /* 4 1 8 1 */ 
} 

.context-menu .separator { 
    -fx-padding: 0.0em 0.333333em 0.0em 0.333333em; /* 0 4 0 4 */ 
} 

.context-menu .scroll-arrow { 
    -fx-padding: 0.416667em 0.416667em 0.416667em 0.416667em; /* 5 */ 
    -fx-background-color: #006699; 
} 

.context-menu .scroll-arrow:hover { 
    -fx-background: -fx-accent; 
    -fx-background-color: #006699; 
    -fx-text-fill: -fx-selection-bar-text; 
} 

.context-menu:show-mnemonics .mnemonic-underline { 
    -fx-stroke: -fx-text-fill; 
} 

Điều này rõ ràng không hoạt động hoặc tôi sẽ không ở đây. Nó dường như không có tác dụng bất kể giá trị tôi thay đổi.

Tôi đã mở JavaFX Scene Builder để xem xét (lưu ý phụ tôi đã sử dụng đây là phương sách cuối cùng, vì tôi thấy nó khá vụng về để sử dụng). Tôi nhận thấy theo các phần có thể theo dõi của phần css cho menu ngữ cảnh là danh sách CSSBridge[context-menu] có vẻ lạ. Những thứ khác như Nhãn có Label[label].

Ai có thể giải thích cho tôi điều gì đang xảy ra ở đây, vì dường như nó bỏ qua tệp css của tôi cho menu ngữ cảnh và sử dụng giá trị mặc định trong caspian.css?


Đính kèm tệp FXML mẫu, css và mã java để chạy.

Sample.fxml

<?xml version="1.0" encoding="UTF-8"?> 

<?import java.lang.*?> 
<?import java.net.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.image.*?> 
<?import javafx.scene.layout.*?> 

<AnchorPane fx:id="myroot" xmlns:fx="http://javafx.com/fxml"> 
    <children> 
    <Label text="Right click for options"> 
     <contextMenu> 
     <ContextMenu> 
      <items> 
      <MenuItem text="Help" /> 
      <MenuItem text="Me" /> 
      </items> 
     </ContextMenu> 
     </contextMenu> 
    </Label> 
    </children> 
    <stylesheets> 
    <URL value="@contextcolor.css" /> 
    </stylesheets> 
</AnchorPane> 

contextcolor.css

.root { 
    -fx-background-color: cornsilk; 
    -fx-padding: 10; 
} 

.context-menu { 
    -fx-background-color: #006699; 
    -fx-text-fill: white; 
} 

.menu-item .label { 
    -fx-text-fill: yellow; 
} 

.menu-item:focused .label { 
    -fx-text-fill: white; 
} 

Test.java

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 

public class Test extends Application { 

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

    @Override 
    public void start(Stage stage) throws Exception { 
     System.out.println(com.sun.javafx.runtime.VersionInfo.getVersion()); 

     Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml")); 

     stage.setScene(new Scene(root)); 
     stage.show(); 
    } 
} 
+0

Cung cấp [phản hồi về SceneBuilder đây] (https://forums.oracle.com/forums/thread .jspa? threadID = 2369765) – jewelsea

+0

Sẽ làm cuối tuần này. Cảm ơn các liên kết. –

Trả lời

14

Đây là một si ví dụ đơn giản về tạo kiểu menu ngữ cảnh JavaFX thông qua css.

Thử nghiệm trên WinXPsp3, Jdk7u6b14ea, JavaFX 2.2b12.

java ứng dụng

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

public class ContextColor extends Application { 
    public static void main(String[] args) { launch(args); } 
    @Override public void start(Stage stage) { 
    Label label = new Label("Right click for options"); 
    label.setContextMenu(new ContextMenu(new MenuItem("Help"), new MenuItem("Me"))); 
    Scene scene = new Scene(label); 
    scene.getStylesheets().add(ContextColor.class.getResource("contextcolor.css").toExternalForm()); 
    stage.setScene(scene); 
    stage.show(); 
    } 
} 

css stylesheet

/** contextcolor.css 
* place in same folder as ContextColor.java 
* ensure your build system copies this file to the ContextColor.class output directory on build 
*/ 
.root { 
    -fx-background-color: cornsilk; 
    -fx-padding: 10; 
} 

.context-menu { 
    -fx-background-color: #006699; 
    -fx-text-fill: white; 
} 

.menu-item .label { 
    -fx-text-fill: yellow; 
} 

.menu-item:focused .label { 
    -fx-text-fill: white; 
} 

Tôi không thể cho bạn biết chính xác lý do tại sao phong cách css của bạn không có chức năng như bạn mong đợi. Một số lý do có thể là:

  1. Bạn không tải đúng cách.
  2. Tệp css của bạn không được sao chép vào đường dẫn đầu ra của bạn.
  3. Tệp css của bạn bị lỗi hoặc không chính xác cú pháp.
  4. Bạn đang sử dụng phiên bản JavaFX cũ hơn có các menu ngữ cảnh tạo kiểu khó khăn từ css.

Cập nhật

Nhìn vào mã hoàn chỉnh trong câu hỏi của bạn, nơi các tập tin css được nạp qua fxml, tôi có thể tạo lại vấn đề của bạn, nơi các menu ngữ cảnh không theo kiểu. Nếu, thay vì đặt biểu định kiểu trong fxml, tôi đặt biểu định kiểu trên scene trong mã (như trong ứng dụng thử nghiệm của tôi), thì tất cả đều hoạt động tốt.

Sự khác biệt khi css được đặt qua fxml là fxml không đặt biểu định kiểu trên cảnh, mà thay vào đó là nút gốc của cảnh. Nếu trong đoạn code tôi thêm biểu định kiểu cho cha mẹ chứ không phải là cảnh, sau đó tôi kết thúc với cùng một hành vi từ việc triển khai mã như fxml. Vì vậy, đây không phải là vấn đề thực sự với fxml, mà là vấn đề với các quy tắc thừa kế của quá trình xử lý css JavaFX 2.2. IMO, quá trình xử lý css là sai - kiểu dáng phải giống nhau nếu biểu định kiểu đã được đặt trên hiện trường hoặc trên nút gốc của cảnh.

Tôi khuyên bạn nên gửi lỗi chống lại các điều khiển thời gian chạy JavaFX tại http://javafx-jira.kenai.com với trường hợp thử nghiệm của bạn và liên kết quay lại câu hỏi StackOverflow này và nhóm JavaFX sẽ giải quyết vấn đề trong thời gian tới.

Cách giải quyết khác, chỉ cần đặt biểu định kiểu của bạn trên hiện trường trong mã ngay bây giờ.


Cập nhật

gốc nguyên nhân cho vấn đề này dường như là RT-19435: popup control not styled be parent's style sheet declarations.

+0

Tôi đang chạy phiên bản 2.1, do đó được cập nhật lên phiên bản 2.2.0-beta. Tôi chạy mẫu của bạn và nó hoạt động. Vì tôi đang sử dụng các tệp FXML, tôi đã chuyển đổi ví dụ của bạn thành một FXML và chạy nó một lần nữa. Thật không may nó không hoạt động của họ. Tôi sẽ cập nhật câu hỏi của tôi với FXML nếu bạn không quan tâm đến việc xem xét nó sẽ được đánh giá cao. –

+0

Cảm ơn bạn đã đăng mã jschoen, tôi đã cập nhật câu trả lời của tôi dựa trên mã đã đăng của bạn. – jewelsea

+0

Tôi đã tạo sự cố mới [# RT-22871] (http://javafx-jira.kenai.com/browse/RT-22871) như được đề xuất. Cảm ơn đã giúp đỡ. –

1
import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Group; 
import javafx.scene.Node; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.scene.control.ContextMenu; 
import javafx.scene.control.Label; 
import javafx.scene.control.MenuItem; 
import javafx.scene.control.TextArea; 
import javafx.scene.image.Image; 
import javafx.scene.image.ImageView; 
import javafx.scene.layout.GridPane; 
import javafx.stage.Stage; 
import javafx.geometry.Insets; 

/** 
* 
* @author nidhi.a.agrawal 
*/ 
public class Context extends Application { 

    @Override 
    public void start(Stage stage) throws Exception { 
     // Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml")); 

     TextArea notification = new TextArea(); 
     ContextMenu contextMenu = new ContextMenu(); 

     Node itemIcon = new ImageView(new Image(getClass().getResourceAsStream("icon_createnew.png"))); 
     Node con_test_hierIcon = new ImageView(new Image(getClass().getResourceAsStream("icon_Configure_Test _Hierachy.png"))); 
     Node cutIcon = new ImageView(new Image(getClass().getResourceAsStream("icon_cut.png"))); 
     Node copyIcon = new ImageView(new Image(getClass().getResourceAsStream("icon_copy.png"))); 
     Node pasteIcon = new ImageView(new Image(getClass().getResourceAsStream("icon_paste.png"))); 
     Node insertIcon = new ImageView(new Image(getClass().getResourceAsStream("icon_insert.png"))); 
     Node editIcon = new ImageView(new Image(getClass().getResourceAsStream("icon_edit.png"))); 
     Node renameIcon = new ImageView(new Image(getClass().getResourceAsStream("icon_rename.png"))); 
     Node deleteIcon = new ImageView(new Image(getClass().getResourceAsStream("icon_delete.png"))); 
     Node tagIcon = new ImageView(new Image(getClass().getResourceAsStream("icon_tag.png"))); 
     Node refreshIcon = new ImageView(new Image(getClass().getResourceAsStream("icon_refresh.png"))); 


     MenuItem sap_new = new MenuItem("Create New Sap System", itemIcon); 
     MenuItem con_test_hier = new MenuItem("Configure Test Hierarchy", con_test_hierIcon); 
     MenuItem cut = new MenuItem("Cut", cutIcon); 
     MenuItem copy = new MenuItem("Copy", copyIcon); 
     MenuItem paste = new MenuItem("Paste", pasteIcon); 
     MenuItem insert = new MenuItem("Insert", insertIcon); 
     MenuItem edit = new MenuItem("Edit", editIcon); 
     MenuItem rename = new MenuItem("Rename", renameIcon); 
     MenuItem delete = new MenuItem("Delete", deleteIcon); 
     MenuItem tag = new MenuItem("Tag", tagIcon); 
     MenuItem refresh = new MenuItem("Refresh", refreshIcon); 

     contextMenu.getItems().addAll(sap_new,con_test_hier,cut,copy,paste,insert,edit,rename,delete,tag,refresh); 
notification.setContextMenu(contextMenu); 
Group root = new Group(); 
     root.getChildren().add(notification); 
     Scene scene = new Scene(root); 
      scene.getStylesheets().add(Context.class.getResource("contextcolor.css").toExternalForm()); 
     stage.setScene(scene); 
     stage.show(); 

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

Đối với những đơn tôi đã thiết syles như thế này: ---

.

root { 
    -fx-background-color: cornsilk; 
    -fx-padding: 10; 
} 

.context-menu { 
    -fx-background-color: #C8CFD7; 
    -fx-border-color: #BBC2CC; 
    -fx-text-fill: white; 
} 


.menu-item .label { 
    -fx-fill:red; 
    -fx-font-family:tahoma; 
    -fx-font-size: 12px;; 
    -fx-stroke:#C8CFD7; 
    -fx-strok-width:.25; 
} 

.menu-item:focused .label { 
    -fx-text-fill: white; 
} 
.menu-item{ 
    -fx-border-color: #DDDEE2 transparent #B9C0C8 transparent; 

    -fx-border-width:0.50px; 

} 
.menu-item:focused { 
    -fx-background: -fx-accent; 
    -fx-background-color: #7092BE; 
    -fx-text-fill: -fx-selection-bar-text; 
} 

nó đang chạy tốt tôi có thể thay đổi màu nền, màu viền, thiết lập biểu tượng vv

Các vấn đề liên quan