Для справки я создаю пример, используя ваш подход; в то время как он работает, он также предлагает проблему фокуса в другом месте вашего кода. Привязки клавиш избегают этого, как показано здесь здесь .
Приложение: Вот ссылка на мое рабочее ключевое слово.
private static class TestPanel extends JPanel {
private static final String LEFT = "Left";
private Action left = new AbstractAction(LEFT) {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(LEFT);
}
};
private static final String RIGHT = "Right";
private Action right = new AbstractAction(RIGHT) {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(RIGHT);
}
};
public TestPanel() {
this.getInputMap().put(
KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), LEFT);
this.getActionMap().put(LEFT, left);
this.getInputMap().put(
KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), RIGHT);
this.getActionMap().put(RIGHT, right);
}
}
Оригинал SSCCE :
import java.awt.EventQueue;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* @see https://stackoverflow.com/a/16531380/230513
*/
public class Test {
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new TestPanel());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static class TestPanel extends JPanel implements KeyListener {
public TestPanel() {
this.addKeyListener(this);
this.setFocusable(true);
this.requestFocusInWindow();
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
System.out.println("Right");
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
System.out.println("Left");
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Test().display();
}
});
}
}
EDIT 2: Этот ответ решает проблему, но не является правильным способом решения проблемы. Вам следует обратиться к ответу Lucero.
Взял этот ответ из: http://www.dotnetspark.com/Forum/314-accessing-hidden-files-and-write-it.aspx
1- Установить файл как видимый, чтобы его можно было перезаписать
// Get file info
FileInfo myFile= new FileInfo(Environment.CurrentDirectory + @"\hiddenFile.txt");
// Remove the hidden attribute of the file
myFile.Attributes &= ~FileAttributes.Hidden;
2- Внести изменения в файл
// Do foo...
3- Установить обратно файл как скрытый
// Put it back as hidden
myFile.Attributes |= FileAttributes.Hidden;
EDIT: Я исправил некоторые проблемы в моем ответе, как упомянул briler
Если это вариант для вас, вы можете попробовать использовать File.SetAttributes
для временного удаления скрытого атрибута, выполните свою работу и затем верните его в предыдущее состояние.
После того, как вы открыли файл, вы можете изменить его атрибуты (в том числе и только для чтения) и продолжить запись в него. Это один из способов предотвратить перезапись файла другими процессами.
Таким образом, можно было бы показать файл, открыть его, а затем восстановить его как скрытое, даже если он открыт.
Например, работает следующий код:
public void WriteToHiddenFile(string fname)
{
TextWriter outf;
FileInfo info;
info = new FileInfo(fname);
info.Attributes = FileAttributes.Normal; // Set file to unhidden
outf = new StreamWriter(fname); // Open file for writing
info.Attributes = FileAttributes.Hidden; // Set back to hidden
outf.WriteLine("test output."); // Write to file
outf.Close(); // Close file
}
Обратите внимание, что файл остается скрытым, пока процесс записывает в него.
Похоже, проблема именно в таком File.Exists ()
проверка выполняется внутренне, что не дает результата, если файл скрыт (например, пытается выполнить FileMode.Create
для уже существующего файла).
Поэтому используйте FileMode.OpenOrCreate
, чтобы убедиться, что файл открывается или создается, даже если он скрыт, или просто FileMode.Open
, если вы не хотите его создавать. если его не существует.
Когда используется FileMode.OpenOrCreate
, файл не будет усечен, поэтому вы должны установить его длину в конце, чтобы убедиться, что после конца текста нет остатков.
using (FileStream fs = new FileStream(filename, FileMode.Open)) {
using (TextWriter tw = new StreamWriter(fs)) {
// Write your data here...
tw.WriteLine("foo");
// Flush the writer in order to get a correct stream position for truncating
tw.Flush();
// Set the stream length to the current position in order to truncate leftover text
fs.SetLength(fs.Position);
}
}
Если вы используете .NET 4.5 или новее, существует новая перегрузка, которая предотвращает удаление StreamWriter
, чтобы также удалить базовый поток. Затем код можно было бы написать немного более интуитивно следующим образом:
using (FileStream fs = new FileStream(filename, FileMode.Open)) {
using (TextWriter tw = new StreamWriter(fs, Encoding.UTF8, 1024, true)) {
// Write your data here...
tw.WriteLine("foo");
}
// Set the stream length to the current position in order to truncate leftover text
fs.SetLength(fs.Position);
}
Вы можете отобразить файл перед записью в него и после завершения записи скрыть его снова.