2015-09-16 6 views
5

मैं इस तरह के समय में प्रवेश करने के लिए एक स्पिनर बनाना चाहता हूं: Youtube Vidéoजावाएफएक्स में टाइमस्पिनर कैसे बनाएं?

यदि कोई जानता है कि स्रोत कोड छुपा रहा है, तो यह सही होगा। लेकिन यदि नहीं, तो मैं इसे स्वयं कोशिश करना और कार्यान्वित करना चाहता हूं, लेकिन मैं इस तरह 3 अलग-अलग (फोकस करने योग्य?) टेक्स्टरेरा कैसे बना सकता हूं?

संपादित करें: यहाँ मैं क्या मिला है, लेकिन मैं घंटे और (सेकंड ऑप्टिकल फाइबर केबल के लिए और एक ही) वेतन वृद्धि घंटे न केवल मिनट

Spinner<LocalTime> spinner = new Spinner(new SpinnerValueFactory() { 

     { 
      setConverter(new LocalTimeStringConverter(FormatStyle.MEDIUM)); 
     } 

     @Override 
     public void decrement(int steps) { 
      if (getValue() == null) 
       setValue(LocalTime.now()); 
      else { 
       LocalTime time = (LocalTime) getValue(); 
       setValue(time.minusMinutes(steps)); 
      } 
     } 

     @Override 
     public void increment(int steps) { 
      if (this.getValue() == null) 
       setValue(LocalTime.now()); 
      else { 
       LocalTime time = (LocalTime) getValue(); 
       setValue(time.plusMinutes(steps)); 
      } 
     } 
    }); 
    spinner.setEditable(true); 

यह परिणाम है का चयन करने में सक्षम करना चाहते हैं मैं:

enter image description here

धन्यवाद

+0

इसे लागू करने का प्रयास करें और यदि आप अटक जाते हैं तो एक विशिष्ट प्रश्न पोस्ट करें। जैसा कि यह खड़ा है, इस मंच के लिए आपका प्रश्न विषय बंद है। –

+0

ठीक है, मुझे यह भी नहीं पता कि वास्तव में कहां से शुरू करना है ... – Phoste

+0

एक 'स्पिनर ' के साथ एक कस्टम 'स्पिनरवेल्यू फैक्टरी' के साथ संभवतः शुरू करें। –

उत्तर

5

मुझे लगता है कि संपादक के अलग अलग हिस्सों के चयन के लिए सबसे अच्छा तरीका टी है o संपादक में caretPosition की जांच करें और आवश्यकतानुसार उचित भाग में वृद्धि/कमी करें। उत्पादन गुणवत्ता करने का इरादा नहीं है, लेकिन एक अच्छी शुरुआत होना चाहिए: यहाँ

import java.time.LocalTime; 
import java.time.format.DateTimeFormatter; 

import javafx.beans.property.ObjectProperty; 
import javafx.beans.property.SimpleObjectProperty; 
import javafx.scene.control.Spinner; 
import javafx.scene.control.SpinnerValueFactory; 
import javafx.scene.control.TextFormatter; 
import javafx.scene.input.InputEvent; 
import javafx.util.StringConverter; 

public class TimeSpinner extends Spinner<LocalTime> { 

    // Mode represents the unit that is currently being edited. 
    // For convenience expose methods for incrementing and decrementing that 
    // unit, and for selecting the appropriate portion in a spinner's editor 
    enum Mode { 

     HOURS { 
      @Override 
      LocalTime increment(LocalTime time, int steps) { 
       return time.plusHours(steps); 
      } 
      @Override 
      void select(TimeSpinner spinner) { 
       int index = spinner.getEditor().getText().indexOf(':'); 
       spinner.getEditor().selectRange(0, index); 
      } 
     }, 
     MINUTES { 
      @Override 
      LocalTime increment(LocalTime time, int steps) { 
       return time.plusMinutes(steps); 
      } 
      @Override 
      void select(TimeSpinner spinner) { 
       int hrIndex = spinner.getEditor().getText().indexOf(':'); 
       int minIndex = spinner.getEditor().getText().indexOf(':', hrIndex + 1); 
       spinner.getEditor().selectRange(hrIndex+1, minIndex); 
      } 
     }, 
     SECONDS { 
      @Override 
      LocalTime increment(LocalTime time, int steps) { 
       return time.plusSeconds(steps); 
      } 
      @Override 
      void select(TimeSpinner spinner) { 
       int index = spinner.getEditor().getText().lastIndexOf(':'); 
       spinner.getEditor().selectRange(index+1, spinner.getEditor().getText().length()); 
      } 
     }; 
     abstract LocalTime increment(LocalTime time, int steps); 
     abstract void select(TimeSpinner spinner); 
     LocalTime decrement(LocalTime time, int steps) { 
      return increment(time, -steps); 
     } 
    } 

    // Property containing the current editing mode: 

    private final ObjectProperty<Mode> mode = new SimpleObjectProperty<>(Mode.HOURS) ; 

    public ObjectProperty<Mode> modeProperty() { 
     return mode; 
    } 

    public final Mode getMode() { 
     return modeProperty().get(); 
    } 

    public final void setMode(Mode mode) { 
     modeProperty().set(mode); 
    } 


    public TimeSpinner(LocalTime time) { 
     setEditable(true); 

     // Create a StringConverter for converting between the text in the 
     // editor and the actual value: 

     DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss"); 

     StringConverter<LocalTime> localTimeConverter = new StringConverter<LocalTime>() { 

      @Override 
      public String toString(LocalTime time) { 
       return formatter.format(time); 
      } 

      @Override 
      public LocalTime fromString(String string) { 
       String[] tokens = string.split(":"); 
       int hours = getIntField(tokens, 0); 
       int minutes = getIntField(tokens, 1) ; 
       int seconds = getIntField(tokens, 2); 
       int totalSeconds = (hours * 60 + minutes) * 60 + seconds ; 
       return LocalTime.of((totalSeconds/3600) % 24, (totalSeconds/60) % 60, seconds % 60); 
      } 

      private int getIntField(String[] tokens, int index) { 
       if (tokens.length <= index || tokens[index].isEmpty()) { 
        return 0 ; 
       } 
       return Integer.parseInt(tokens[index]); 
      } 

     }; 

     // The textFormatter both manages the text <-> LocalTime conversion, 
     // and vetoes any edits that are not valid. We just make sure we have 
     // two colons and only digits in between: 

     TextFormatter<LocalTime> textFormatter = new TextFormatter<LocalTime>(localTimeConverter, LocalTime.now(), c -> { 
      String newText = c.getControlNewText(); 
      if (newText.matches("[0-9]{0,2}:[0-9]{0,2}:[0-9]{0,2}")) { 
       return c ; 
      } 
      return null ; 
     }); 

     // The spinner value factory defines increment and decrement by 
     // delegating to the current editing mode: 

     SpinnerValueFactory<LocalTime> valueFactory = new SpinnerValueFactory<LocalTime>() { 


      { 

       setConverter(localTimeConverter); 
       setValue(time); 
      } 

      @Override 
      public void decrement(int steps) { 
       setValue(mode.get().decrement(getValue(), steps)); 
       mode.get().select(TimeSpinner.this); 
      } 

      @Override 
      public void increment(int steps) { 
       setValue(mode.get().increment(getValue(), steps)); 
       mode.get().select(TimeSpinner.this); 
      } 

     }; 

     this.setValueFactory(valueFactory); 
     this.getEditor().setTextFormatter(textFormatter); 

     // Update the mode when the user interacts with the editor. 
     // This is a bit of a hack, e.g. calling spinner.getEditor().positionCaret() 
     // could result in incorrect state. Directly observing the caretPostion 
     // didn't work well though; getting that to work properly might be 
     // a better approach in the long run. 
     this.getEditor().addEventHandler(InputEvent.ANY, e -> { 
      int caretPos = this.getEditor().getCaretPosition(); 
      int hrIndex = this.getEditor().getText().indexOf(':'); 
      int minIndex = this.getEditor().getText().indexOf(':', hrIndex + 1); 
      if (caretPos <= hrIndex) { 
       mode.set(Mode.HOURS); 
      } else if (caretPos <= minIndex) { 
       mode.set(Mode.MINUTES); 
      } else { 
       mode.set(Mode.SECONDS); 
      } 
     }); 

     // When the mode changes, select the new portion: 
     mode.addListener((obs, oldMode, newMode) -> newMode.select(this)); 

    } 

    public TimeSpinner() { 
     this(LocalTime.now()); 
    } 
} 

और एक त्वरित है तुम भी

यहां एक त्वरित प्रयास है संपादक की अनुमति दी इनपुट को नियंत्रित करने, आदि पर एक TextFormatter सेट कर सकते हैं इसे प्रयोग के उदाहरण:

import java.time.format.DateTimeFormatter; 

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 


public class TimeSpinnerExample extends Application { 
    @Override 
    public void start(Stage primaryStage) { 

     TimeSpinner spinner = new TimeSpinner(); 

     DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm:ss a"); 
     spinner.valueProperty().addListener((obs, oldTime, newTime) -> 
      System.out.println(formatter.format(newTime))); 

     StackPane root = new StackPane(spinner); 
     Scene scene = new Scene(root, 350, 120); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

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

बहुत बहुत धन्यवाद, यह सोचा है कि यह अधिक जटिल है जैसा मैंने सोचा था। Altough मैंने आपके कोड की कोशिश की लेकिन मुझे स्पिनर – Phoste

+0

में वृद्धि या कमी करने का प्रयास करने पर एक NullPointerException मिलता है मैंने इसे अपने कामकाजी उदाहरण से कॉपी किया है। एनपीई पाने के लिए आपने क्या किया? यह किस लाइन से था? प्रत्येक enum मोड में वृद्धि विधि पर –

+0

। ऐसा लगता है कि स्पिनर मान शून्य था, मैंने अभी कन्स्ट्रक्टर में एक सेटवैल्यू (टाइम) जोड़ा और यह ठीक काम करता है;) – Phoste

0

परिवर्तन आपके कनवर्टर निर्माता रहे हैं:

setConverter(new LocalTimeStringConverter(DateTimeFormatter.ofPattern("HH:mm"), DateTimeFormatter.ofPattern("HH:mm"))); 

enter image description here

संबंधित मुद्दे