2015-12-08 4 views
1

У меня есть JSpinner с SpinnerDateModel формата «HH: mm». Я хочу, чтобы пользователь мог (например) копировать дату из «yyyy-MM-dd HH: mm: ss.SSS» из таблицы (или любого другого источника) и вставлять ее в JSpinner - HH: mm часть только. Такая полная строка даты обычно недействительна для компонента, но я все еще хочу попробовать вставленную строку и получить нужную информацию от нее (если она есть) ... Я думал, что мой метод проверки должен выглядеть примерно так, как показано ниже, но я не знаю «т знает, как изменить поведение пасты(), так что я могу добавить проверку и изменение вставленного текста ...Как проверить и изменить строку, прежде чем вставлять ее в JSpinner?

 private String validateAndReturnCorrected(String pastedText) { 

      DateFormat hoursMinutesFormat = new SimpleDateFormat("HH:mm"); 
      try { 
       // trying to paste a full date string? 
       DateFormat fullDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 
       Date date = fullDateFormat.parse(pastedText); 
       return hoursMinutesFormat.format(date); 
      } catch (ParseException ex) { 
      } 
      // trying to paste hour and minutes? 
      try { 
       Date date = hoursMinutesFormat.parse(pastedText); 
       return hoursMinutesFormat.format(date); 
      } catch (ParseException ex1) { 
      } 
      // trying to paste date in HH:mm:ss format? 
      try { 
       DateFormat hoursMinutesSecondsFormat = new SimpleDateFormat("HH:mm:ss"); 
       Date date = hoursMinutesSecondsFormat.parse(pastedText); 
       return hoursMinutesSecondsFormat.format(date); 
      } catch (ParseException ex2) { 
      } 
      // trying to paste date in HH:mm:ss.SSS format? 
      try { 
       DateFormat hoursMinutesSecondsMilisecondsFormat = new SimpleDateFormat("HH:mm:ss.SSS"); 
       Date date = hoursMinutesSecondsMilisecondsFormat.parse(pastedText); 
       return hoursMinutesFormat.format(date); 
      } catch (ParseException ex3) { 
      } 

      // unable to correct the string... 
      return ""; 

     } 

UPDATE

изменения гугла вопроса я нашел следующие два сайта, которые привели меня к решению проблемы:

Таким образом, решение выглядит примерно так:

class ProxyAction extends TextAction implements ClipboardOwner { 

    private TextAction action; 

    public ProxyAction(TextAction action) { 
     super(action.toString()); 
     this.action = action; 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     String cbc=getClipboardContents(); 
     setClipboardContents(validateAndReturnCorrected(cbc)); 
     action.actionPerformed(e); 
     setClipboardContents(cbc); 
     System.out.println("Paste Occured..............................................................."); 
    } 

// here goes the validateAndReturnCorrected method 

    public String getClipboardContents() { 
     String result = ""; 
     try { 
      result = (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor); 
     } catch (UnsupportedFlavorException | IOException ex) { 
      ex.printStackTrace(); 
     } 
     return result; 
    } 

    public void setClipboardContents(String aString) { 
     StringSelection stringSelection = new StringSelection(aString); 
     Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 
     clipboard.setContents(stringSelection, this); 
    } 

    @Override 
    public void lostOwnership(Clipboard clipboard, Transferable contents) { 
    } 
} 
+0

Вот вопрос, который может вам помочь: http: // stackoverflow.com/questions/3707485/how-to-convert-string-to-date-without-know-the-format Возможно ли это, чтобы пользователь вставлял дату в текстовое поле и позволял пользователю изменять ввод, если это необходимо? –

+0

Нет, он должен попытаться исправить вставляемую строку автоматически ... Я думаю, мне нужен способ переопределить мой метод javascript jspinner или что-то подобное ... В вопросе, который вы связали, рассматривается проблема получения даты из строки но я думаю, что я делаю это нормально в опубликованном методе проверки. – ssr

ответ

0

Я думаю, что вы должны быть в состоянии это в 2 этапа.

  1. Сначала вам нужно прикрепить ChangeListener на JSpinner.
  2. Затем, используя метод stateChanged, вы выполняете проверку и применяете изменения к значению.
+0

Я пробовал это, но я не мог заставить слушателя отличить пасту от обычного редактирования, сделанного путем ввода. – ssr

+0

Просто попробовал еще раз, чтобы узнать, в чем проблема с ним, и метод stateChanged срабатывает только после успешного завершения редактирования. Я мог бы сделать setCommitsOnValidEdit (true) для форматирования, но это также не заставит его работать, как я хочу - он просто запустит его при каждом набранном символе и т. Д. ... Я хочу, чтобы изменить вставную строку в то время вставки его в текстовое поле. Например, у моего буфера обмена есть дата в полном формате, но мой код изменит строку «на лету» до формата «HH: mm» и вставляет ее в поле или подобное. – ssr

2

Я хочу, чтобы пользователь (например) возможность скопировать дату в «гггг-ММ-ДД чч: мм: СС.ссс» из таблицы (или любого другого источника) и пасты это в JSpinner - только часть HH: mm.

  • это простая вещь реализуется в JSpinners Xxx(Spinner)Model и зависит от - если это SimpleDateFormat добавлен в JSpinner

  • проверки входных данных (SpinnerEditor), просто JFormattedTextField по умолчанию (для получения дополнительной информации к читать конфигурации JFormattedTextFields и InputVerifier) ​​

  • например (основы и стандарты, без переопределения или установки чего-то особенного), Дата изменения с 08. декабря до 10 декабря и час от 10 до 7 утра

.

enter image description here

.

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.GraphicsEnvironment; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.text.DateFormat; 
import java.text.SimpleDateFormat; 
import javax.swing.AbstractSpinnerModel; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JSpinner; 
import javax.swing.SpinnerDateModel; 
import javax.swing.SpinnerListModel; 
import javax.swing.SpinnerNumberModel; 

public class JSpinnerTest { 

    public static final int DEFAULT_WIDTH = 400; 
    public static final int DEFAULT_HEIGHT = 250; 
    private JFrame frame = new JFrame(); 
    private JPanel mainPanel = new JPanel(new GridLayout(0, 3, 10, 10)); 
    private JButton okButton = new JButton("Ok"); 
    private JPanel buttonPanel = new JPanel(); 

    public JSpinnerTest() { 
     buttonPanel.add(okButton); 
     mainPanel = new JPanel(); 
     mainPanel.setLayout(new GridLayout(0, 3, 10, 10)); 

     JSpinner defaultSpinner = new JSpinner(); 
     addRow("Default", defaultSpinner); 
     JSpinner boundedSpinner = new JSpinner(new SpinnerNumberModel(5, 0, 10, 0.5)); 
     addRow("Bounded", boundedSpinner); 
     String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment() 
       .getAvailableFontFamilyNames(); 
     JSpinner listSpinner = new JSpinner(new SpinnerListModel(fonts)); 
     addRow("List", listSpinner); 
     JSpinner reverseListSpinner = new JSpinner(new SpinnerListModel(fonts) { 
      private static final long serialVersionUID = 1L; 

      @Override 
      public Object getNextValue() { 
       return super.getPreviousValue(); 
      } 

      @Override 
      public Object getPreviousValue() { 
       return super.getNextValue(); 
      } 
     }); 
     addRow("Reverse List", reverseListSpinner); 
     JSpinner dateSpinner = new JSpinner(new SpinnerDateModel()); 
     addRow("Date", dateSpinner); 
     JSpinner betterDateSpinner = new JSpinner(new SpinnerDateModel()); 
     String pattern = ((SimpleDateFormat) DateFormat.getDateInstance()).toPattern(); 
     betterDateSpinner.setEditor(new JSpinner.DateEditor(betterDateSpinner, pattern)); 
     addRow("Better Date", betterDateSpinner); 
     JSpinner timeSpinner = new JSpinner(new SpinnerDateModel()); 
     pattern = ((SimpleDateFormat) DateFormat.getTimeInstance(DateFormat.SHORT)).toPattern(); 
     timeSpinner.setEditor(new JSpinner.DateEditor(timeSpinner, pattern)); 
     addRow("Time", timeSpinner); 
     JSpinner permSpinner = new JSpinner(new PermutationSpinnerModel("meat")); 
     addRow("Word permutations", permSpinner); 
     frame.setTitle("SpinnerTest"); 
     frame.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 
     frame.add(buttonPanel, BorderLayout.SOUTH); 
     frame.add(mainPanel, BorderLayout.CENTER); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    private void addRow(String labelText, final JSpinner spinner) { 
     mainPanel.add(new JLabel(labelText)); 
     mainPanel.add(spinner); 
     final JLabel valueLabel = new JLabel(); 
     mainPanel.add(valueLabel); 
     okButton.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent event) { 
       Object value = spinner.getValue(); 
       valueLabel.setText(value.toString()); 
      } 
     }); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JSpinnerTest frame = new JSpinnerTest(); 

      } 
     }); 
    } 
} 

class PermutationSpinnerModel extends AbstractSpinnerModel { 

    private static final long serialVersionUID = 1L; 

    /** 
    * Constructs the model. 
    * 
    * @param w the word to permute 
    */ 
    public PermutationSpinnerModel(String w) { 
     word = w; 
    } 

    @Override 
    public Object getValue() { 
     return word; 
    } 

    @Override 
    public void setValue(Object value) { 
     if (!(value instanceof String)) { 
      throw new IllegalArgumentException(); 
     } 
     word = (String) value; 
     fireStateChanged(); 
    } 

    @Override 
    public Object getNextValue() { 
     int[] codePoints = toCodePointArray(word); 
     for (int i = codePoints.length - 1; i > 0; i--) { 
      if (codePoints[i - 1] < codePoints[i]) { 
       int j = codePoints.length - 1; 
       while (codePoints[i - 1] > codePoints[j]) { 
        j--; 
       } 
       swap(codePoints, i - 1, j); 
       reverse(codePoints, i, codePoints.length - 1); 
       return new String(codePoints, 0, codePoints.length); 
      } 
     } 
     reverse(codePoints, 0, codePoints.length - 1); 
     return new String(codePoints, 0, codePoints.length); 
    } 

    @Override 
    public Object getPreviousValue() { 
     int[] codePoints = toCodePointArray(word); 
     for (int i = codePoints.length - 1; i > 0; i--) { 
      if (codePoints[i - 1] > codePoints[i]) { 
       int j = codePoints.length - 1; 
       while (codePoints[i - 1] < codePoints[j]) { 
        j--; 
       } 
       swap(codePoints, i - 1, j); 
       reverse(codePoints, i, codePoints.length - 1); 
       return new String(codePoints, 0, codePoints.length); 
      } 
     } 
     reverse(codePoints, 0, codePoints.length - 1); 
     return new String(codePoints, 0, codePoints.length); 
    } 

    private static int[] toCodePointArray(String str) { 
     int[] codePoints = new int[str.codePointCount(0, str.length())]; 
     for (int i = 0, j = 0; i < str.length(); i++, j++) { 
      int cp = str.codePointAt(i); 
      if (Character.isSupplementaryCodePoint(cp)) { 
       i++; 
      } 
      codePoints[j] = cp; 
     } 
     return codePoints; 
    } 

    private static void swap(int[] a, int i, int j) { 
     int temp = a[i]; 
     a[i] = a[j]; 
     a[j] = temp; 
    } 

    private static void reverse(int[] a, int i, int j) { 
     while (i < j) { 
      swap(a, i, j); 
      i++; 
      j--; 
     } 
    } 
    private String word; 
} 
+0

Кажется, я не могу скопировать строку «Дата» и добавить ее в «Лучшую дату» или «Время», чтобы они «получили» нужные им части из значения буфера обмена ... Или Я что-то делаю неправильно? Есть ли способ изменить то, что вставлено? – ssr

+0

Я просто понял, что вы меня неправильно поняли: я хочу, чтобы иметь возможность скопировать всю дату и вставить всю дату, но вставляемая строка будет изменена в момент вставки только для включения действительных данных (в моем случае она должна быть вставить полную дату только в часовую и минутную часть - я не хочу, чтобы пользователю приходилось делать это вручную, «интеллектуальное» вставка дат). – ssr

+0

@ssr 1. для лучшей помощи в ближайшее время опубликовано краткое, выполняемое, компилируемое, компилируемое, обобщающее, основополагающее обходное средство (неправильное и скремблированное значение) SSCCE/MCVE (дата изменена с 08. декабрь на 10. декабрь и час с 10 утра до 7 утра), в моем ответе есть несколько способов, но (не хотите догадываться, нет ли у вас часов, минут или минут и минут, а что реальное значение в модели и форматированный вывод на экране) – mKorbel

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

  • Нет связанных вопросов^_^