2015-01-03 2 views
1

Я знаю, что вы можете установить сцену, чтобы иметь стиль утилиты «Stage.InitStyle (StageStyle.UTILITY)»; и вы можете настроить его на прозрачный стиль «Stage.InitStyle (StageStyle.TRANSPARENT)»; но можете ли вы и на том же этапе? Я устал делать это так, чтобы сцена не показывалась как окно вниз в меню «Пуск», и я хотел бы, чтобы сцена была невидимой, чтобы вы могли видеть только сцену.Возможно ли иметь прозрачную полезную ступень в javafx?

+2

http://stackoverflow.com/questions/15502451/a-javafx-stage-could-be-both-stagestyle-utility-and-stagestyle-transparent? –

+1

«Сцена имеет один из следующих стилей:« (из JavaDocs) предложит не ... – MadProgrammer

+0

Значит, это невозможно – sazzy4o

ответ

3

Вы всегда можете сделать это по-старому, используя Swing, где эта функция доступна. А Swing позволяет встраивать JavaFX. Конечно, было бы предпочтительнее иметь чистый механизм без Swing, но afaik он не существует (пока).

Пример:

import javafx.application.Platform; 
import javafx.embed.swing.JFXPanel; 
import javafx.scene.Scene; 
import javafx.scene.control.ContextMenu; 
import javafx.scene.control.Label; 
import javafx.scene.control.MenuItem; 
import javafx.scene.layout.Background; 
import javafx.scene.layout.StackPane; 
import javafx.scene.paint.Color; 
import javafx.scene.paint.CycleMethod; 
import javafx.scene.paint.RadialGradient; 
import javafx.scene.paint.Stop; 

import javax.swing.JFrame; 
import javax.swing.SwingUtilities; 

import java.awt.geom.GeneralPath; 

public class Widget extends JFrame { 

    class DragContext { 
     double x; 
     double y; 
    } 

    public Widget() { 

     // decoration 
     setType(Type.UTILITY); 
     setUndecorated(true); 

     setSize(200, 200); 

     toBack(); 

     // position 
     // setLocation(100, 100); 
     setLocationRelativeTo(null); // centers on screen 

     // frame operations 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     // frame shape (a star) 
     double points[][] = { { 0, 85 }, { 75, 75 }, { 100, 10 }, { 125, 75 }, { 200, 85 }, { 150, 125 }, { 160, 190 }, { 100, 150 }, { 40, 190 }, { 50, 125 }, { 0, 85 } }; 
     GeneralPath star = new GeneralPath(); 
     star.moveTo(points[0][0], points[0][1]); 
     for (int k = 1; k < points.length; k++) 
      star.lineTo(points[k][0], points[k][2]); 
     star.closePath(); 

     setShape(star); 

     // embed fx into swing 
     JFXPanel fxPanel = new JFXPanel(); 

     Widget.this.getContentPane().add(fxPanel); 

     Platform.runLater(new Runnable() { 
      @Override 
      public void run() { 

       // set scene in JFXPanel 
       fxPanel.setScene(createFxScene()); 

       // show frame 
       SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 

         Widget.this.setVisible(true); 

         // send it to the desktop, behind all other existing windows 
         // Widget.this.toBack(); 
         // Widget.this.repaint(); 
        } 
       }); 
      } 
     }); 

    } 

    private Scene createFxScene() { 

     StackPane rootPane = new StackPane(); 
     rootPane.setBackground(Background.EMPTY); 

     // add some node 
     Label label = new Label("Bright & Shiny"); 
     label.setTextFill(Color.RED); 

     rootPane.getChildren().add(label); 

     // create scene 
     Scene scene = new Scene(rootPane); 

     // gradient fill 
     RadialGradient radialGradient = new RadialGradient(270, 0.8, 0.5, 0.5, 0.7, true, CycleMethod.NO_CYCLE, new Stop(.5f, Color.YELLOW), new Stop(.7f, Color.ORANGE), new Stop(.9f, Color.ORANGERED)); 
     scene.setFill(radialGradient); 

     // context menu with close button 
     ContextMenu contextMenu = new ContextMenu(); 

     MenuItem closeMenuItem = new MenuItem("Close"); 
     closeMenuItem.setOnAction(actionEvent -> System.exit(0)); 

     contextMenu.getItems().add(closeMenuItem); 

     // set context menu for scene 
     scene.setOnMousePressed(mouseEvent -> { 
      if (mouseEvent.isSecondaryButtonDown()) { 
       contextMenu.show(rootPane, mouseEvent.getScreenX(), mouseEvent.getScreenY()); 
      } 
     }); 

     // allow the frame to be dragged around 
     final DragContext dragDelta = new DragContext(); 

     rootPane.setOnMousePressed(mouseEvent -> { 

      dragDelta.x = Widget.this.getLocation().getX() - mouseEvent.getScreenX(); 
      dragDelta.y = Widget.this.getLocation().getY() - mouseEvent.getScreenY(); 

     }); 

     rootPane.setOnMouseDragged(mouseEvent -> Widget.this.setLocation((int) (mouseEvent.getScreenX() + dragDelta.x), (int) (mouseEvent.getScreenY() + dragDelta.y))); 

     return scene; 
    } 

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

} 

Вот скриншот виджета, который не отображается в панели задач. Перетащите его левой кнопкой мыши. Правая кнопка мыши предлагает контекстное меню с кнопкой закрытия.

Widget

Код выше использует форму свинг фрейма. В приведенном ниже коде используется форма управления javafx.

Вот версия, в которой видна только элемент управления. Я использую элемент управления ярлыком.

Если вы хотите отправить элемент управления прямо на рабочий стол, вам необходимо активировать вызов toBack(). Вы можете масштабировать управление с помощью колеса мыши. Максимальный размер масштабирования ограничен размером jframe.

Все, что вам нужно сделать для пользовательского элемента управления, это реализовать код в createFxControl()

import javafx.application.Platform; 
import javafx.embed.swing.JFXPanel; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.control.ContextMenu; 
import javafx.scene.control.Control; 
import javafx.scene.control.Label; 
import javafx.scene.control.MenuItem; 
import javafx.scene.effect.Reflection; 
import javafx.scene.input.ScrollEvent; 
import javafx.scene.layout.Background; 
import javafx.scene.layout.StackPane; 
import javafx.scene.paint.Color; 
import javafx.scene.text.Font; 

import javax.swing.JFrame; 
import javax.swing.SwingUtilities; 

public class LabelWidget extends JFrame { 

    class DragContext { 
     double x; 
     double y; 
    } 

    public LabelWidget() { 

     // decoration 
     setType(Type.UTILITY); 
     setUndecorated(true); 

     // make frame transparent, we only want the control to be visible 
     setBackground(new java.awt.Color(0,0,0,0)); 

     setSize(400, 400); 

     // position 
     // setLocation(100, 100); 
     setLocationRelativeTo(null); // centers on screen 

     // frame operations 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     // embed fx into swing 
     JFXPanel fxPanel = new JFXPanel(); 

     LabelWidget.this.getContentPane().add(fxPanel); 

     Platform.runLater(new Runnable() { 
      @Override 
      public void run() { 

       // set scene in JFXPanel 
       fxPanel.setScene(createFxScene()); 

       // show frame 
       SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 

         LabelWidget.this.setVisible(true); 

         // send it to the desktop, behind all other existing windows 
         // ClockWidget.this.toBack(); 
         // ClockWidget.this.repaint(); 
        } 
       }); 
      } 
     }); 

    } 

    private Scene createFxScene() { 

     StackPane rootPane = new StackPane(); 

     // make pane transparent, we only want the control to be visible 
     rootPane.setBackground(Background.EMPTY); 

     // add control 
     Control control = createFxControl(); 
     rootPane.getChildren().add(control); 

     // create scene 
     Scene scene = new Scene(rootPane); 

     // make scene transparent, we only want the control to be visible 
     scene.setFill(Color.TRANSPARENT); 

     // context menu with close button 
     ContextMenu contextMenu = new ContextMenu(); 

     MenuItem closeMenuItem = new MenuItem("Close"); 
     closeMenuItem.setOnAction(actionEvent -> System.exit(0)); 

     contextMenu.getItems().add(closeMenuItem); 

     control.setContextMenu(contextMenu); 

     // allow the frame to be dragged around 
     makeDraggable(control); 

     // allow zooming 
     makeZoomable(control); 

     return scene; 
    } 
    /** 
    * Create the JavaFX control of which we use the shape. 
    * @return 
    */ 
    private Control createFxControl() { 

     Label label = new Label("I'm a Label"); 
     label.setFont(new Font("Tahoma", 24)); 
     label.setEffect(new Reflection()); 

     return label; 
    } 



    /** 
    * Allow dragging of the stage/control on the desktop 
    * @param control 
    * @param stage 
    */ 
    public void makeDraggable(Control control) { 

     final DragContext dragDelta = new DragContext(); 

     control.setOnMousePressed(mouseEvent -> { 

      dragDelta.x = LabelWidget.this.getLocation().getX() - mouseEvent.getScreenX(); 
      dragDelta.y = LabelWidget.this.getLocation().getY() - mouseEvent.getScreenY(); 

     }); 

     control.setOnMouseDragged(mouseEvent -> LabelWidget.this.setLocation((int) (mouseEvent.getScreenX() + dragDelta.x), (int) (mouseEvent.getScreenY() + dragDelta.y))); 

    } 

    /** 
    * Allow zooming 
    * @param control 
    */ 
    public void makeZoomable(Control control) { 

     // note: in order to make it larger, we'd have to resize the stage/frame => we limit the size to 1.0 for now and allow only making the control smaller 
     final double MAX_SCALE = 1.0; 
     final double MIN_SCALE = 0.1; 
     control.addEventFilter(ScrollEvent.ANY, new EventHandler<ScrollEvent>() { 
      @Override 
      public void handle(ScrollEvent event) { 
       double delta = 1.2; 
       double scale = control.getScaleX(); 
       if (event.getDeltaY() < 0) { 
        scale /= delta; 
       } else { 
        scale *= delta; 
       } 
       scale = clamp(scale, MIN_SCALE, MAX_SCALE); 
       control.setScaleX(scale); 
       control.setScaleY(scale); 
       event.consume(); 
      } 
     }); 

    } 

    /** 
    * Limit bounds of value 
    * @param value 
    * @param min 
    * @param max 
    * @return 
    */ 
    public static double clamp(double value, double min, double max) { 
     if(Double.compare(value, min) < 0) 
      return min; 
     if(Double.compare(value, max) > 0) 
      return max; 
     return value; 
    } 

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

} 

Или если у вас есть огромная библиотека Энцо из https://github.com/HanSolo/Enzo под рукой, вы можете использовать этот код:

private Control createFxControl() { 

    // create a clock using the enzo library from https://github.com/HanSolo/Enzo 
    Clock clock = ClockBuilder.create() 
      // .prefSize(400, 400) 
      .design(Clock.Design.DB) 
      .running(true) 
      .text("Berlin") 
      .autoNightMode(true) 
      .build(); 


    return clock; 
} 

создать это:

enter image description here

2

Нашел простой способ сделать это: Создайте окно утилиты и сделайте его полностью прозрачным, чтобы вы не могли видеть или взаимодействовать с ним. Затем создайте нужное окно и запустите владельца в окне утилиты - это приведет к тому, что он не появится на панели задач.

+0

Простой и легкий ... Спасибо за это интересное решение ... Помогло мне много – Developer66

Смежные вопросы