खिड़की को सामने कैसे लाएँ?


90

हमारे पास एक जावा एप्लिकेशन है जिसे अग्रभूमि में लाने की आवश्यकता होती है जब एक टेलीकांस्ट्रोल तंत्र आवेदन में कुछ सक्रिय करता है।

इसे प्राप्त करने के लिए, हमने कक्षा के उस तरीके को महसूस किया है जो JFrameकार्यान्वयन के बाद हमारे आवेदन के फ्रेम (विस्तार ) का प्रतिनिधित्व करता है :

setVisible(true);
toFront();

विंडोज एक्सपी के तहत, यह पहली बार काम करता है इसे कहा जाता है, दूसरी बार टास्कबार में केवल टैब चमकता है, फ्रेम अब सामने नहीं आता है। वही Win2k के लिए चला जाता है। विस्टा पर यह ठीक काम करने लगता है।

आपके पास कोई विचार है?


क्या आपके पास इस व्यवहार के लिए एक नमूना है?
ऑस्करराइज

3
उचित उत्तर का toFront()उपयोग कर EDT पर कॉल करना है invokeLater। नीचे एक सरल उत्तर शामिल है, लेकिन यह स्वीकृत उत्तर नहीं है। यह काम करता है, यद्यपि। पूरी तरह से।
एरिक रॉबर्टसन

मुझे पता है कि यह पुराना है, लेकिन यह OSX
ferdil

मैं इस समस्या का सामना कर रहा हूं, लेकिन नीचे दिए गए उत्तरों में से कोई भी इसे हल नहीं करता है। मुझे यकीन है कि यह विंडोज़ के कारण है जो मुझे एप्लिकेशन में मेरी पहली विंडो के लिए 'चोरी' फोकस करने की अनुमति नहीं देता है।
क्रेग वॉरेन

जवाबों:


69

एक संभावित समाधान है:

java.awt.EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {
        myFrame.toFront();
        myFrame.repaint();
    }
});

8
शायद पहली जगह में सभी यूआई कोड को इनवॉकेलेटर के अंदर शुरू करना चाहिए? ;)
java.is.for.desktop.indeed

2
केडीई 4.9.5 पर जावा 7 में मेरे लिए काम नहीं किया, खिड़की अभी भी अन्य कार्यक्रमों के नीचे छिपाएगी। क्या मदद मिली कि मैं खिड़कियों को सामने लाने का क्रम बदल रहा था। एक खिड़की को छिपाने और दूसरी खिड़की दिखाने के बजाय, दूसरी खिड़की दिखाएं और फिर पहली खिड़की (JFrame) छिपाएं।
लेकेनस्टाइन

1
विंडोज 10 के साथ एक एप्लेट में जावा 1.8 चल रहा है
इलियट

प्रतिलोम विधि क्या होगी?
कार्डिनल - मोनिका

33

मुझे JFrameउबंटू (जावा 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)

चूंकि मैं उबंटू 9.04 में चला गया, इसलिए लगता है कि WindowListenerआह्वान करने की कोई आवश्यकता नहीं है super.setAlwaysOnTop(false)- जैसा कि देखा जा सकता है; इस कोड को विधियों में ले जाया गया toFront()और setVisible()

कृपया ध्यान दें कि setVisible()ईडीटी पर विधि हमेशा लागू होनी चाहिए।


धन्यवाद! यह भी संबंधित है यह सवाल: stackoverflow.com/questions/2315560/…
rogerdpack

यह मेरे द्वारा संकलित नहीं है क्योंकि setDisposed () विधि है। नहीं मिल सकता है।
ka3ak

1
@ ka3ak यह एक संरक्षित सेटर है जिसे सुझावित JFrame- बेस क्लास में पेश किया जा सकता है ताकि स्थिति का पता लगाया जा सके। मेथड डिस्पोज () को एक कॉल के साथ ओवरराइड करने की आवश्यकता होगी जिसे सेटिस्पोज्ड (सच) किया जाएगा। यह कड़ाई से सबके लिए आवश्यक नहीं है।
01

1
.setAlwaysOnTop(true);केवल एक ही है कि मेरे लिए काम किया है जब एक JWindow का उपयोग कर रहा था।
डीजीबर्गबर्ग

setAlwaysOnTop(true)एक ही तरीका है कि मैं इसे विंडोज़ 10 के तहत चला रहा हूं - धन्यवाद!
हार्टमुट पी।

22

विंडोज़ में विंडोज़ को फ़ोकस चुराने से रोकने की सुविधा है; इसके बजाय यह टास्कबार आइकन को फ्लैश करता है। XP में यह डिफ़ॉल्ट रूप से चालू है (एकमात्र स्थान जिसे मैंने बदलने के लिए देखा है वह TweakUI का उपयोग कर रहा है, लेकिन कहीं-कहीं रजिस्ट्री सेटिंग है)। विस्टा में उन्होंने डिफ़ॉल्ट को बदल दिया है और / या इसे आउट-ऑफ-द-बॉक्स यूआई के साथ एक उपयोगकर्ता सुलभ सेटिंग के रूप में उजागर कर सकते हैं।

विंडोज़ को खुद को सामने से मजबूर करने और ध्यान केंद्रित करने से रोकना विंडोज 2K (और मैं, एक के लिए, इसके लिए आभारी हूं) के बाद से एक विशेषता है।

उस ने कहा, मेरे पास एक छोटा सा जावा ऐप है जिसे मैं काम करते समय अपनी गतिविधियों को रिकॉर्ड करने के लिए याद दिलाने के लिए उपयोग करता हूं, और यह हर 30 मिनट में खुद को सक्रिय विंडो बनाता है (कॉन्फ़िगर करने योग्य, निश्चित रूप से)। यह हमेशा विंडोज एक्सपी के तहत लगातार काम करता है और टाइटल बार विंडो को कभी भी फ्लैश नहीं करता है। यह निम्नलिखित कोड का उपयोग करता है, जिसे यूआई थ्रेड में टाइमर इवेंट फायरिंग के रूप में कहा जाता है:

if(getState()!=Frame.NORMAL) { setState(Frame.NORMAL); }
toFront();
repaint();

(पहली पंक्ति पुनर्स्थापित करता है अगर छोटा किया जाता है ... वास्तव में यह इसे पुनर्स्थापित करेगा यदि अधिकतम भी हो, लेकिन मेरे पास ऐसा कभी नहीं है)।

जबकि मेरे पास आमतौर पर यह ऐप कम से कम है, अक्सर यह मेरे टेक्स्ट एडिटर के पीछे होता है। और, जैसा मैंने कहा, यह हमेशा काम करता है।

मुझे इस बात का अंदाजा है कि आपकी समस्या क्या हो सकती है - शायद आपके पास सेटविजिबल () कॉल के साथ दौड़ की स्थिति है। जब तक खिड़की वास्तव में प्रदर्शित नहीं होती है, तब तक () मान्य नहीं हो सकता है; मुझे पहले भी requestFocus () के साथ यह समस्या आई है। आपको एक विंडो सक्रिय इवेंट में UI श्रोता में toFront () कॉल लगाने की आवश्यकता हो सकती है।

2014-09-07: कुछ समय में उपरोक्त कोड ने काम करना बंद कर दिया था, शायद जावा 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 के अनुसार, यह कोड ठीक काम कर रहा है।


1
+1 फ़ोकस चोरी करने के लिए विंडोज़ को अनुमति नहीं देने के लिए समर्थन करता है। जब मैं किसी दस्तावेज़ में टाइप कर रहा होता हूं तो मुझे नफरत होती है।
केन पॉल

1
मैं पूरी तरह से ध्यान केंद्रित करने के खिलाफ आपसे सहमत हूं, लेकिन इस सटीक मामले में उपयोगकर्ता को उम्मीद है कि आवेदन सामने आएगा। लेकिन यह रजिस्ट्री सेटिंग्स को बदलने और विंडोज़ के संपूर्ण व्यवहार को बदलने के लिए अनकूल होगा।
7

मैं अनुमान लगा रहा हूं super.setAlwaysOnTop(false);कि क्या खिड़की हमेशा शीर्ष पर नहीं है , जो trueखिड़की से सामने लाने के लिए पहले से सेट किए गए से छुटकारा पाने के लिए आवश्यक है , सही है? मैं पूछ रहा हूं क्योंकि आपके कोड के साथ मेरे मामले में खिड़की अभी भी शीर्ष पर है, जो मुझे स्पष्ट रूप से नहीं चाहिए। विंडोज 10 पर रनिंग jre1.8.0_66
ब्रैम

@ बम: हाँ यह सही है। मैं जावा और विंडोज के एक ही संस्करण पर कोड चला रहा हूं और यह हमेशा अन्य खिड़कियों के शीर्ष पर समाप्त नहीं होता है। यह हमेशा शीर्ष पर सेट करने के लिए आवश्यक नहीं हो सकता है, लेकिन मुझे लगता है अन्यथा विंडोज सिर्फ शीर्षक बार को चमकता है, कम से कम कुछ शर्तों के तहत।
लॉरेंस डोल

हम्म, अजीब है। क्या आप एक ऐसे ही प्रश्न पर एक नज़र डाल सकते हैं, जिसमें मैं इस उत्तर को जोड़ता हूं? शायद यह कोड अधिक स्पष्ट रूप से इस मुद्दे को दिखाता है: stackoverflow.com/questions/34637597/…
ब्रैम वनरॉय

11

यहाँ एक तरीका है जो वास्तव में काम करता है (विंडोज विस्टा पर परीक्षण): डी

   frame.setExtendedState(JFrame.ICONIFIED);
   frame.setExtendedState(fullscreen ? JFrame.MAXIMIZED_BOTH : JFrame.NORMAL);

फुलस्क्रीन चर इंगित करता है कि आप एप्लिकेशन को पूर्ण स्क्रीन या विंडो चलाना चाहते हैं।

यह कार्य पट्टी को फ्लैश नहीं करता है, लेकिन खिड़की को मज़बूती से सामने लाएं।


SetExtendedState टिप के लिए धन्यवाद। मैंने इसे विंडो के साथ फोरग्राउंड () और रिपेंट () सॉल्यूशन के साथ उपयोग किया ताकि खिड़की को अग्रभूमि में लाया जा सके, भले ही इसे कम से कम किया गया हो।
लूटने

1
पुष्टि की गई: यह समाधान कार्य पट्टी में संदेश को चमकाने के लिए परिणाम में WindowsXP का उपयोग करता है। धन्यवाद!
एरिक लिंडॉयर

5

Hj, फेडोरा 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 :-) में काम करता है


थोड़ा हैकी, हमारे लिए काम करता है, लेकिन केवल पहली कॉल के लिए :-)। (
कुबंटु

यह एकमात्र समाधान था जो मेरे लिए (विंडोज सर्वर 2012 R2) एक ऐसे मुद्दे के लिए काम करता था जहां एक JFrame (लॉगिन) खोला जाता है, लेकिन जब तक उपयोगकर्ता उस पर क्लिक नहीं करता है तब तक उसका ध्यान केंद्रित नहीं होता है।
ग्लेननरू

4

यह सरल विधि मेरे लिए विंडोज 7 में पूरी तरह से काम करती है:

    private void BringToFront() {
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                if(jFrame != null) {
                    jFrame.toFront();
                    jFrame.repaint();
                }
            }
        });
    }

2
repaint()आवश्यक नहीं है, invokeLater()यह किया। धन्यवाद।
Matthieu

4

मैंने आपके उत्तरों का परीक्षण किया और केवल स्टीफन रीच ने मेरे लिए काम किया। हालाँकि मैं विंडो को उसकी पिछली स्थिति (अधिकतम / सामान्य) में पुनर्स्थापित करने का प्रबंधन नहीं कर सका। मुझे यह परिवर्तन बेहतर लगा:

view.setState(java.awt.Frame.ICONIFIED);
view.setState(java.awt.Frame.NORMAL);

यही कारण है setStateकी बजाय setExtendedState


3

सबसे सरल तरीका मैंने पाया है कि प्लेटफार्मों में असंगतता नहीं है:

setVisible (गलत); setVisible (सही);


1
कुछ पलक झपकने का कारण नहीं है? अच्छा और सरल हालांकि :)
rogerdpack

मेरी पृष्ठभूमि प्रक्रिया के लिए काम नहीं किया। यदि अग्रभूमि प्रक्रिया से कॉल किया जाता है, तो भी खिड़की पहले ताज़ा के लिए सफेद आती है। स्क्रीन ग्रेड के लिए उपयोग नहीं किया जा सकता है।
ड्रैगनलाड

विंडो के
आइकॉन होने

2

जब आप .toFront () एक JFrame खिड़कियों और linux में समान होते हैं, तो क्या होता है, यह नियम

-> यदि मौजूदा एप्लिकेशन की एक विंडो वर्तमान में केंद्रित विंडो है, तो अनुरोधित विंडो पर स्वैप करें -> यदि नहीं, तो विंडो केवल टास्कबार में चमकती है

परंतु :

-> नई विंडो अपने आप फोकस हो जाती हैं

तो चलिए इसका फायदा उठाते हैं! आप एक खिड़की को सामने लाना चाहते हैं, यह कैसे करना है? कुंआ :

  1. एक खाली गैर-उद्देश्य विंडो बनाएँ
  2. इसे दिखाना
  3. स्क्रीन पर दिखाने के लिए इसके लिए प्रतीक्षा करें (सेटविज़ुअल ऐसा करता है)
  4. जब दिखाया जाता है, तो उस विंडो पर ध्यान देने का अनुरोध करें जिसे आप वास्तव में फोकस में लाना चाहते हैं
  5. खाली खिड़की को छिपाना, उसे नष्ट करना

या, जावा कोड में:

// 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);
  }
});

Win7 पर काम नहीं किया, दोनों विंडोज़ फ्लैश (यदि मैं 2 को छिपा नहीं करता हूं)।
नैट्स

रचनात्मक। Win7 पर मेरी पृष्ठभूमि प्रक्रिया के लिए काम नहीं किया, जब कवर किया। नया फ्रेम ऊपर नहीं आता है। पुराना JDK 6u21।
ड्रैगनलाड

0

वहाँ कई हैं चेतावनियां विधि toFront () जो आपकी समस्या का कारण बनने के लिए जावाडोक में।

लेकिन मैं वैसे भी एक अनुमान लगाऊंगा, जब "केवल टास्कबार में टैब चमकता है", तो क्या आवेदन को कम कर दिया गया है? यदि ऐसा है तो javadoc से निम्न पंक्ति लागू हो सकती है:

"यदि यह विंडो दिखाई दे रही है, तो इस विंडो को सामने लाता है और इसे केंद्रित विंडो बना सकता है।"


0

खिड़की से ध्यान हटाने से बचने के लिए जब इसकी ज़रूरत के सभी छिपे होने के बाद दिखाई देने पर वापस लौटना है:

setExtendedState(JFrame.NORMAL);

इस तरह:

defaultItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                showWindow();
                setExtendedState(JFrame.NORMAL);
            }
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.