У нас есть Java-приложение, которое необходимо вывести на передний план, когда механизм телеуправления активирует что-то в приложении.
Чтобы получить это, мы реализовали в вызываемом методе класса, который представляет собой фрейм нашего приложения (расширение a JFrame
), следующую реализацию:
setVisible(true);
toFront();
В Windows XP это работает при первом вызове, во второй раз мигает только вкладка на панели задач, рамка больше не выходит на передний план. То же самое и с Win2k. В Vista вроде нормально работает.
Есть ли у вас какие-либо идеи?
toFront()
EDT с помощьюinvokeLater
. Ниже приведен простой ответ, но это не принятый ответ. Однако это действительно работает. Отлично.Ответы:
Возможное решение:
java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { myFrame.toFront(); myFrame.repaint(); } });
источник
У меня была такая же проблема с
JFrame
выводом на передний план в Ubuntu (Java 1.6.0_10). И единственный способ решить эту проблему - предоставитьWindowListener
. В частности, мне пришлось настроить мой так,JFrame
чтобы он всегда оставался наверху при каждомtoFront()
вызове, и предоставитьwindowDeactivated
обработчик событий дляsetAlwaysOnTop(false)
.Итак, вот код, который можно разместить в базе
JFrame
, которая используется для получения всех фреймов приложения.@Override public void setVisible(final boolean visible) { // make sure that frame is marked as not disposed if it is asked to be visible if (visible) { setDisposed(false); } // let's handle visibility... if (!visible || !isVisible()) { // have to check this condition simply because super.setVisible(true) invokes toFront if frame was already visible super.setVisible(visible); } // ...and bring frame to the front.. in a strange and weird way if (visible) { toFront(); } } @Override public void toFront() { super.setVisible(true); int state = super.getExtendedState(); state &= ~JFrame.ICONIFIED; super.setExtendedState(state); super.setAlwaysOnTop(true); super.toFront(); super.requestFocus(); super.setAlwaysOnTop(false); }
Всякий раз, когда ваша рамка должна быть отображена или вынесена на первый план
frame.setVisible(true)
.С тех пор, как я перешел на Ubuntu 9.04, похоже, нет необходимости в использовании
WindowListener
для вызоваsuper.setAlwaysOnTop(false)
- как можно заметить; этот код был перенесен в методыtoFront()
иsetVisible()
.Обратите внимание, что метод
setVisible()
всегда следует вызывать в EDT.источник
.setAlwaysOnTop(true);
был единственный, который работал у меня при использовании JWindow.setAlwaysOnTop(true)
это единственный способ заставить его работать под Windows 10 - спасибо!В Windows есть возможность предотвратить кражу фокуса окнами; вместо этого мигает значок на панели задач. В XP он включен по умолчанию (единственное место, где я видел, чтобы изменить его, - это TweakUI, но где-то есть параметр реестра). В Vista они могли изменить значение по умолчанию и / или выставить его как доступную пользователю настройку с помощью готового пользовательского интерфейса.
Предотвращение того, чтобы окна выдвигались вперед и фокусировались, - это функция, появившаяся еще с Windows 2K (и я, например, благодарен за это).
Тем не менее, у меня есть небольшое Java-приложение, которое я использую, чтобы напоминать мне о записи моих действий во время работы, и оно делает себя активным окном каждые 30 минут (конечно, настраиваемым). Он всегда работает стабильно под Windows XP и никогда не мигает в окне заголовка. Он использует следующий код, вызываемый в потоке пользовательского интерфейса в результате срабатывания события таймера:
if(getState()!=Frame.NORMAL) { setState(Frame.NORMAL); } toFront(); repaint();
(первая строка восстанавливается, если свернута ... на самом деле она восстановит ее, если она развернута, но у меня этого никогда не было).
Обычно это приложение свернуто, но зачастую оно просто находится за моим текстовым редактором. И, как я уже сказал, это всегда работает.
У меня есть представление о том, в чем может быть ваша проблема - возможно, у вас есть состояние гонки с вызовом setVisible (). toFront () может быть недействительным, если окно фактически не отображается при его вызове; У меня раньше была эта проблема с requestFocus (). Возможно, вам потребуется поместить вызов toFront () в прослушиватель пользовательского интерфейса для события, активируемого окном.
2014-09-07: В какой-то момент указанный выше код перестал работать, возможно, на Java 6 или 7. После некоторого исследования и экспериментов мне пришлось обновить код, чтобы переопределить метод окна,
toFront
сделав это (вместе с измененным кодом из того, что выше):setVisible(true); toFront(); requestFocus(); repaint(); ... public @Override void toFront() { int sta = super.getExtendedState() & ~JFrame.ICONIFIED & JFrame.NORMAL; super.setExtendedState(sta); super.setAlwaysOnTop(true); super.toFront(); super.requestFocus(); super.setAlwaysOnTop(false); }
Что касается Java 8_20, этот код, похоже, работает нормально.
источник
super.setAlwaysOnTop(false);
это так, что окно не всегда сверху, что необходимо, чтобы избавиться от того, чтоtrue
мы установили ранее, чтобы вывести окно на передний план, верно? Я спрашиваю, потому что с вашим кодом в моем случае окно все еще всегда наверху, чего я, очевидно, не хочу. Запуск jre1.8.0_66 в Windows 10.Вот метод, который ДЕЙСТВИТЕЛЬНО работает (проверено в Windows Vista): D
Переменная полноэкранного режима указывает, хотите ли вы, чтобы приложение работало в полноэкранном или оконном режиме.
При этом панель задач не мигает, но надежно выводится окно вперед.
источник
Эй, все ваши методы у меня не работают в Fedora KDE 14. У меня есть грязный способ вывести окно на передний план, пока мы ждем, пока Oracle исправит эту проблему.
import java.awt.MouseInfo; import java.awt.Point; import java.awt.Robot; import java.awt.event.InputEvent; public class FrameMain extends javax.swing.JFrame { //... private final javax.swing.JFrame mainFrame = this; private void toggleVisible() { setVisible(!isVisible()); if (isVisible()) { toFront(); requestFocus(); setAlwaysOnTop(true); try { //remember the last location of mouse final Point oldMouseLocation = MouseInfo.getPointerInfo().getLocation(); //simulate a mouse click on title bar of window Robot robot = new Robot(); robot.mouseMove(mainFrame.getX() + 100, mainFrame.getY() + 5); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); //move mouse to old location robot.mouseMove((int) oldMouseLocation.getX(), (int) oldMouseLocation.getY()); } catch (Exception ex) { //just ignore exception, or you can handle it as you want } finally { setAlwaysOnTop(false); } } } //... }
И это отлично работает в моей Fedora KDE 14 :-)
источник
Этот простой метод отлично работал у меня в Windows 7:
private void BringToFront() { java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { if(jFrame != null) { jFrame.toFront(); jFrame.repaint(); } } }); }
источник
repaint()
не нужно,invokeLater()
он сделал это. Спасибо.Я проверил ваши ответы, и только ответ Стефана Райха работал у меня. Хотя мне не удалось восстановить окно в его предыдущее состояние (развернутое / нормальное). Я нашел эту мутацию лучше:
То есть
setState
вместоsetExtendedState
.источник
Самый простой способ, который я нашел, не имеет противоречий между платформами:
setVisible (ложь); setVisible (правда);
источник
Правила, определяющие, что происходит, когда вы .toFront () JFrame одинаковы в Windows и Linux:
-> если окно существующего приложения в настоящее время является окном в фокусе, то фокус переключается на запрошенное окно -> если нет, окно просто мигает на панели задач
НО :
-> новые окна автоматически получают фокус
Так что давайте использовать это! Хотите вывести окно вперед, как это сделать? Что ж :
Или в Java-коде:
// unminimize if necessary this.setExtendedState(this.getExtendedState() & ~JFrame.ICONIFIED); // don't blame me, blame my upbringing // or better yet, blame java ! final JFrame newFrame = new JFrame(); newFrame.add(new JLabel("boembabies, is this in front ?")); newFrame.pack(); newFrame.setVisible(true); newFrame.toFront(); this.toFront(); this.requestFocus(); // I'm not 100% positive invokeLater is necessary, but it seems to be on // WinXP. I'd be lying if I said I understand why SwingUtilities.invokeLater(new Runnable() { @Override public void run() { newFrame.setVisible(false); } });
источник
В документации javadoc есть множество предостережений для метода toFront (), которые могут вызывать вашу проблему.
Но все равно угадываю, когда "мигает только вкладка в панели задач", приложение свернуто? В таком случае может применяться следующая строка из javadoc:
«Если это Окно видно, переносит это Окно на передний план и может сделать его окном в фокусе».
источник
Чтобы окно не потеряло фокус при его возвращении в видимое состояние после скрытия, все, что необходимо:
Вот так:
defaultItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { showWindow(); setExtendedState(JFrame.NORMAL); } });
источник