refactor ChatFrame

This commit is contained in:
Sergey Ponomarev
2026-07-16 23:09:37 +03:00
parent 2a2e33204f
commit f99786812c

View File

@ -12,7 +12,7 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
*/
package org.jivesoftware.spark.ui;
import org.jivesoftware.MainWindow;
@ -30,6 +30,8 @@ import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.CopyOnWriteArrayList;
import static org.jivesoftware.spark.util.GraphicUtils.centerWindowOnScreen;
/**
* The Window used to display the ChatRoom container.
*/
@ -37,86 +39,65 @@ public class ChatFrame extends JFrame implements WindowFocusListener {
private long inactiveTime;
private boolean focused;
private final JCheckBox alwaysOnTopItem;
private final ChatFrame chatFrame = this;
private final CopyOnWriteArrayList<ChatFrameToFrontListener> _windowToFrontListeners = new CopyOnWriteArrayList<>();
public ChatFrame() {
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
alwaysOnTopItem = new JCheckBox();
alwaysOnTopItem.setToolTipText(Res.getString("menuitem.always.on.top"));
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
alwaysOnTopItem = new JCheckBox();
alwaysOnTopItem.setToolTipText(Res.getString("menuitem.always.on.top"));
LocalPreferences pref = SettingsManager.getLocalPreferences();
alwaysOnTopItem.addActionListener(actionEvent -> {
if (alwaysOnTopItem.isSelected())
{
pref.setChatWindowAlwaysOnTop(true);
chatFrame.setAlwaysOnTop(true);
}
else
{
pref.setChatWindowAlwaysOnTop(false);
chatFrame.setAlwaysOnTop(false);
}
} );
if (pref.isChatWindowAlwaysOnTop())
{
alwaysOnTopItem.setSelected(true);
chatFrame.setAlwaysOnTop(true);
pref.setChatWindowAlwaysOnTop(alwaysOnTopItem.isSelected());
setAlwaysOnTop(alwaysOnTopItem.isSelected());
});
if (pref.isChatWindowAlwaysOnTop()) {
alwaysOnTopItem.setSelected(true);
setAlwaysOnTop(true);
}
setIconImage(SparkManager.getApplicationImage().getImage());
getContentPane().setLayout(new BorderLayout());
getContentPane().add(SparkManager.getChatManager().getChatContainer(), BorderLayout.CENTER);
setMinimumSize( new Dimension( 300, 300 ) );
setMinimumSize(new Dimension(300, 300));
final Rectangle chatFrameBounds = LayoutSettingsManager.getLayoutSettings().getChatFrameBounds();
if (chatFrameBounds == null || chatFrameBounds.width <= 0 || chatFrameBounds.height <= 0)
{
if (chatFrameBounds == null || chatFrameBounds.width <= 0 || chatFrameBounds.height <= 0) {
// Use default settings.
setSize(500, 400);
GraphicUtils.centerWindowOnScreen(this);
}
else
{
setBounds( chatFrameBounds );
centerWindowOnScreen(this);
} else {
setBounds(chatFrameBounds);
}
addComponentListener( new ComponentAdapter()
{
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized( ComponentEvent e )
{
public void componentResized(ComponentEvent e) {
// Don't do this for subclasses.
if ( e.getComponent().getClass().getSimpleName().equalsIgnoreCase( "ChatFrame" ) )
{
LayoutSettingsManager.getLayoutSettings().setChatFrameBounds( getBounds() );
if (e.getComponent().getClass().getSimpleName().equalsIgnoreCase("ChatFrame")) {
LayoutSettingsManager.getLayoutSettings().setChatFrameBounds(getBounds());
}
}
@Override
public void componentMoved( ComponentEvent e )
{
public void componentMoved(ComponentEvent e) {
// Don't do this for subclasses.
if ( e.getComponent().getClass().getSimpleName().equalsIgnoreCase( "ChatFrame" ) )
{
LayoutSettingsManager.getLayoutSettings().setChatFrameBounds( getBounds() );
if (e.getComponent().getClass().getSimpleName().equalsIgnoreCase("ChatFrame")) {
LayoutSettingsManager.getLayoutSettings().setChatFrameBounds(getBounds());
}
}
} );
});
addWindowFocusListener(this);
// Setup WindowListener to be the proxy to the actual window listener
// which cannot normally be used outside of the Window component because
// of protected access.
// Set up WindowListener to be the proxy to the actual window listener,
// which cannot normally be used outside the Window component because of protected access.
addWindowListener(new WindowAdapter() {
/**
* This event fires when the window has become active.
*
* @param e WindowEvent is not used.
*/
@Override
public void windowActivated(WindowEvent e) {
public void windowActivated(WindowEvent e) {
inactiveTime = 0;
if (Spark.isMac()) {
setJMenuBar(MainWindow.getInstance().getMenu());
@ -124,25 +105,22 @@ public class ChatFrame extends JFrame implements WindowFocusListener {
}
/**
* Invoked when a window is de-activated.
* Invoked when a window is deactivated.
*/
@Override
public void windowDeactivated(WindowEvent e) {
public void windowDeactivated(WindowEvent e) {
inactiveTime = System.currentTimeMillis();
}
/**
* This event fires whenever a user minimizes the window
* from the toolbar.
*
* @param e WindowEvent is not used.
* This event fires whenever a user minimizes the window from the toolbar.
*/
@Override
public void windowIconified(WindowEvent e) {
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
public void windowDeiconified(WindowEvent e) {
setFocusableWindowState(true);
}
});
@ -150,12 +128,11 @@ public class ChatFrame extends JFrame implements WindowFocusListener {
// Adding a Resize Listener to validate component sizes in a Chat Room.
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
public void componentResized(ComponentEvent e) {
try {
ChatRoom chatRoom = SparkManager.getChatManager().getChatContainer().getActiveChatRoom();
chatRoom.getVerticalSplitPane().setDividerLocation(-1);
}
catch (ChatRoomNotFoundException e1) {
} catch (ChatRoomNotFoundException e1) {
// Ignore, because I don't care if it's not a chat room.
}
}
@ -163,32 +140,28 @@ public class ChatFrame extends JFrame implements WindowFocusListener {
}
@Override
public void windowGainedFocus(WindowEvent e) {
public void windowGainedFocus(WindowEvent e) {
focused = true;
if(this instanceof MainWindow){
if (this instanceof MainWindow) {
return;
}
SparkManager.getChatManager().getChatContainer().focusChat();
}
@Override
public void windowLostFocus(WindowEvent e) {
public void windowLostFocus(WindowEvent e) {
focused = false;
}
/**
* Returns true if the frame is in focus, otherwise returns false.
*
* @return true if the frame is in focus, otherwise returns false.
*/
public boolean isInFocus() {
return focused;
}
/**
* Returns time the ChatFrame has not been in focus.
*
* @return the time in milliseconds.
* Returns time in milliseconds the ChatFrame has not been in focus.
*/
public long getInactiveTime() {
if (inactiveTime == 0) {
@ -223,40 +196,31 @@ public class ChatFrame extends JFrame implements WindowFocusListener {
* set if the chatFrame should always stay on top
*/
public void setWindowAlwaysOnTop(boolean active) {
SettingsManager.getLocalPreferences().setChatWindowAlwaysOnTop(active);
chatFrame.setAlwaysOnTop(active);
this.fireWindowOnTopListeners(active);
SettingsManager.getLocalPreferences().setChatWindowAlwaysOnTop(active);
setAlwaysOnTop(active);
fireWindowOnTopListeners(active);
}
private void fireWindowOnTopListeners( boolean active )
{
for ( ChatFrameToFrontListener listener : _windowToFrontListeners )
{
try
{
listener.updateStatus( active );
}
catch ( Exception e )
{
Log.error( "A ChatFrameToFrontListener (" + listener + ") threw an exception while processing a 'updateStatus' event with status: " + active, e );
private void fireWindowOnTopListeners(boolean active) {
for (ChatFrameToFrontListener listener : _windowToFrontListeners) {
try {
listener.updateStatus(active);
} catch (Exception e) {
Log.error("A ChatFrameToFrontListener (" + listener + ") threw an exception while processing a 'updateStatus' event with status: " + active, e);
}
}
}
/**
* removes the Window to Front Listener for specified {@link ChatRoom}
*/
public void removeWindowToFrontListener(ChatRoom chatRoom) {
_windowToFrontListeners.remove(chatRoom);
_windowToFrontListeners.remove(chatRoom);
}
/**
* Remove listeners from the "window-alway-on-top" information
* Add listeners for the "window-alway-on-top" information
*/
public void addWindowToFronListener(ChatRoom chatRoom) {
_windowToFrontListeners.addIfAbsent(chatRoom);
fireWindowOnTopListeners(chatFrame.isAlwaysOnTop());
_windowToFrontListeners.addIfAbsent(chatRoom);
fireWindowOnTopListeners(isAlwaysOnTop());
}
}