-
Notifications
You must be signed in to change notification settings - Fork 243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to customize the Window (icon and title) #613
Comments
What you see is the behaviour of SwingTerminal*Frame*.
You could also use class SwingTerminal (without Frame) and add the Frame
with any icon and title you like.
I recommend looking at the SwingTerminalFrame class (source or docs) to see
if it already has methods to set title
and icon (I don't know), or in the source on how it could inspire you to
wrap the SwingTerminal in your own Frame. :-)
…On Thu, Oct 3, 2024 at 1:31 AM Ivar Grahn ***@***.***> wrote:
Hello, I'm building a small terminal app using lanterna, I'm pretty much
done with my use-case but I noticed this little detail:
image.png (view on web)
<https://github.com/user-attachments/assets/d4369671-088f-4558-96cd-2b4f29ad0d29>
Is there any way to customize the Window title and icon? I would like to
use my own icon, and I'd rather not it said "SwingTerminalFrame".
—
Reply to this email directly, view it on GitHub
<#613>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABIDBMVJKKTQUO32ASJG5NDZZR65PAVCNFSM6AAAAABPIVKPICVHI2DSMVQWIX3LMV43ASLTON2WKOZSGU3DEOBRG4ZTMMI>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Just to understand you a bit better when you say "Use SwingTerminal class". Here is a code snippet: final Terminal terminal = terminalFactory.createTerminal();
screen = new TerminalScreen(terminal);
screen.startScreen();
//Setting up basic GUI
multiWindowTextGUI = new MultiWindowTextGUI(new SeparateTextGUIThread.Factory(), screen);
((AsynchronousTextGUIThread) multiWindowTextGUI.getGUIThread()).start();
//Creating window
BasicWindow window = new BasicWindow("Utility Terminal");
window.setHints(Arrays.asList(Window.Hint.CENTERED, Window.Hint.FIT_TERMINAL_WINDOW, Window.Hint.FULL_SCREEN)); Instead of creating a |
yes. instead of using the factory, you create a SwingTerminal directly, and
use some geometry manager to put the SwingTerminal into your application's
main-window.
Ivar Grahn ***@***.***> schrieb am Do., 3. Okt. 2024, 13:05:
… Just to understand you a bit better when you say "Use SwingTerminal
class". Here is a code snippet:
final Terminal terminal = terminalFactory.createTerminal();
screen = new TerminalScreen(terminal);
screen.startScreen();
//Setting up basic GUI
multiWindowTextGUI = new MultiWindowTextGUI(new SeparateTextGUIThread.Factory(), screen);
((AsynchronousTextGUIThread) multiWindowTextGUI.getGUIThread()).start();
//Creating window
BasicWindow window = new BasicWindow("Utility Terminal");
window.setHints(Arrays.asList(Window.Hint.CENTERED, Window.Hint.FIT_TERMINAL_WINDOW, Window.Hint.FULL_SCREEN));
Instead of creating a new Terminal() and new TerminalScreen(terminal, I
could create an explicit SwingTerminal-instance? Is that what you mean?
—
Reply to this email directly, view it on GitHub
<#613 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABIDBMTA4Z57VTYU73CJES3ZZUQGXAVCNFSM6AAAAABPIVKPICVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOJRGEZTCNZYGE>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
but also take a look at the defaultterminalfactory class - it might already
allow you to set options for the swingterminalframe that it creates for you
on certain environments.
Andreas Leitgeb ***@***.***> schrieb am Do., 3. Okt. 2024, 13:48:
… yes. instead of using the factory, you create a SwingTerminal directly,
and use some geometry manager to put the SwingTerminal into your
application's main-window.
Ivar Grahn ***@***.***> schrieb am Do., 3. Okt. 2024, 13:05:
> Just to understand you a bit better when you say "Use SwingTerminal
> class". Here is a code snippet:
>
> final Terminal terminal = terminalFactory.createTerminal();
>
> screen = new TerminalScreen(terminal);
> screen.startScreen();
>
> //Setting up basic GUI
> multiWindowTextGUI = new MultiWindowTextGUI(new SeparateTextGUIThread.Factory(), screen);
> ((AsynchronousTextGUIThread) multiWindowTextGUI.getGUIThread()).start();
>
> //Creating window
> BasicWindow window = new BasicWindow("Utility Terminal");
> window.setHints(Arrays.asList(Window.Hint.CENTERED, Window.Hint.FIT_TERMINAL_WINDOW, Window.Hint.FULL_SCREEN));
>
> Instead of creating a new Terminal() and new TerminalScreen(terminal, I
> could create an explicit SwingTerminal-instance? Is that what you mean?
>
> —
> Reply to this email directly, view it on GitHub
> <#613 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/ABIDBMTA4Z57VTYU73CJES3ZZUQGXAVCNFSM6AAAAABPIVKPICVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOJRGEZTCNZYGE>
> .
> You are receiving this because you commented.Message ID:
> ***@***.***>
>
|
Ah, I'm with you. I'll take a look at it asap. Thanks for the pointers! |
Alright, I got things working, but I'm not fully pleased with my solution. First off, how I did it: public static void runGui() {
DefaultTerminalFactory terminalFactory = new DefaultTerminalFactory().setMouseCaptureMode(
MouseCaptureMode.CLICK);
try {
final SwingTerminalFrame terminal = (SwingTerminalFrame) terminalFactory.createTerminal();
terminal.setTitle("DFObs");
terminal.setIconImage(AssetUtil.getApplicationIconImage());
screen = new TerminalScreen(terminal);
screen.startScreen(); The problem here is that I assume The solution I would want is this: public static void runGui() {
DefaultTerminalFactory terminalFactory = new DefaultTerminalFactory().setMouseCaptureMode(
MouseCaptureMode.CLICK);
try {
final SwingTerminalFrame swingTerminal = terminalFactory.createSwingTerminal();
swingTerminal.setTitle("DFObs");
swingTerminal.setIconImage(AssetUtil.getApplicationIconImage());
screen = new TerminalScreen(swingTerminal);
screen.startScreen(); ... where I explicitly create a SwingTerminal. However, when trying to create my screen using
Is my usage of the factory wrong somehow, or is this a bug? EDIT: An effort to flesh out the question a bit more: Why is |
First thing to understand is: Lanterna's point is in what happens in the
terminal itself.
It's a convenience for platforms that don't have proper "tty"-semanctics,
that Lanterna
offers a graphical implementation of a Terminal as a Window(in the
graphical OS's sense),
to let the "Text User Interface" still work.
Setting the title and icon in the factory is the correct thing, unless
your application only
ever makes sense in graphical context. By setting it for the factory, the
factory can still
decide to instead run it inside the session (e.g. gnome-terminal) and
ignore title and icon.
The error you get appears to be an artifact of a yet "empty" application.
On exiting the
"runGui", lantera normally doesn't expect that the size of the terminal
hasn't yet been
determined. It could be seen as a bug, and it should just suppress that
error, but in practice
it shouldn't matter, because when filling the main window with application
logic, then it
would ask the (Swing)Terminal about its size, and then the size wouldn't be
0 anymore.
…On Fri, Oct 4, 2024 at 12:05 AM Ivar Grahn ***@***.***> wrote:
Alright, I got things working, but I'm not fully pleased with my solution.
First off, how I did it:
public static void runGui() {
DefaultTerminalFactory terminalFactory = new DefaultTerminalFactory().setMouseCaptureMode(
MouseCaptureMode.CLICK);
try {
final SwingTerminalFrame terminal = (SwingTerminalFrame) terminalFactory.createTerminal();
terminal.setTitle("DFObs");
terminal.setIconImage(AssetUtil.getApplicationIconImage());
screen = new TerminalScreen(terminal);
screen.startScreen();
The problem here is that I assume terminalFactory.createTerminal() will
always return a SwingTerminalFrame. I am testing this on my own Linux
machine and I don't set any config in regards to "forceAwt" or "forceText",
but it's still a big "if".
The solution I would want is this:
public static void runGui() {
DefaultTerminalFactory terminalFactory = new DefaultTerminalFactory().setMouseCaptureMode(
MouseCaptureMode.CLICK);
try {
final SwingTerminalFrame swingTerminal = terminalFactory.createSwingTerminal();
swingTerminal.setTitle("DFObs");
swingTerminal.setIconImage(AssetUtil.getApplicationIconImage());
screen = new TerminalScreen(swingTerminal);
screen.startScreen();
... where I explicitly create a SwingTerminal. However, when trying to
create my screen using new Terminal(swingTerminal) it throws the
following error:
Exception in thread "main" java.lang.IllegalArgumentException: Width (0) and height (0) cannot be <= 0
at java.desktop/java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1016)
at java.desktop/java.awt.image.BufferedImage.<init>(BufferedImage.java:324)
at com.googlecode.lanterna.terminal.swing.GraphicalTerminalImplementation.ensureGraphicBufferHasRightSize(GraphicalTerminalImplementation.java:494)
at com.googlecode.lanterna.terminal.swing.GraphicalTerminalImplementation.updateBackBuffer(GraphicalTerminalImplementation.java:332)
at com.googlecode.lanterna.terminal.swing.GraphicalTerminalImplementation.flush(GraphicalTerminalImplementation.java:799)
at com.googlecode.lanterna.terminal.swing.GraphicalTerminalImplementation.exitPrivateMode(GraphicalTerminalImplementation.java:667)
at com.googlecode.lanterna.terminal.swing.SwingTerminal.exitPrivateMode(SwingTerminal.java:264)
at com.googlecode.lanterna.terminal.swing.SwingTerminalFrame.exitPrivateMode(SwingTerminalFrame.java:242)
at com.googlecode.lanterna.screen.TerminalScreen.stopScreen(TerminalScreen.java:123)
at com.googlecode.lanterna.screen.TerminalScreen.stopScreen(TerminalScreen.java:106)
at gui.DfObsGui.runGui(DfObsGui.java:106)
at DfObsMain.main(DfObsMain.java:5)
Is my usage of the factory wrong somehow, or is this a bug?
—
Reply to this email directly, view it on GitHub
<#613 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABIDBMX36OM43F352NF2JL3ZZW5TDAVCNFSM6AAAAABPIVKPICVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOJSGQZDAOJVGE>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
the exception you showed earlier seems to habe been thrown out of the
exitPrivateMode out of runGui's "finally"-block.
if any exception is thrown from startScreen or from TerminalScreen
creation, then post that exception here - as caught in the IDE.
For now I also don't know why one throws and the other not, but the
original exception might help find the cause.
Ivar Grahn ***@***.***> schrieb am Fr., 4. Okt. 2024, 23:36:
… I do comprehend that the purpose of this library is to provide a nice API
to populate a TUI within terminals (or emulated terminals). As such I
respect that when you have more specific requirements for the runtime
itself, as I had with title and icons, you might have to think outside the
"lanterna box". This I agree with 100%.
When testing different workarounds by manipulating the SwingTerminalFrame
however, I tried to utilize the "createSwingTerminal()"-method, and
discovered that this specific method causes a crash when creating the
screen-instance.
In short, when using the library to create the SwingTerminal explicitly,
my code will not reach the populating of the GUI:
image.png (view on web)
<https://github.com/user-attachments/assets/6f007552-d841-4308-b2dd-dec809922694>
It feels a bit too specific not to be faulty. Because if I change to code
to this, the exception is not thrown:
image.png (view on web)
<https://github.com/user-attachments/assets/aaa4bb57-7e4a-440b-931f-1b8fd0c4071a>
I'm a little bit confused by this, because when debugging I can see that
both variants pasted above will result in a call to the same method:
image.png (view on web)
<https://github.com/user-attachments/assets/f7272e69-efbe-4a25-b028-52a097909f3f>
For now I can work around this problem by setting up the factory and cast
the returned Terminal to SwingTerminalFrame, because I know it's of that
type, but it feels like factory.createSwingTerminal() should return an
instance very similar to the SwingTerminalFrame-instance that
factory.createTerminalEmulator() provides, which doesn't result in a
crash.
—
Reply to this email directly, view it on GitHub
<#613 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABIDBMSEVMP2632HEKB6K7TZZ4C6BAVCNFSM6AAAAABPIVKPICVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOJUG4YDENZQGM>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
I think I traced it down. When starting the screen constructed from a SwingTerminalFrame created by the Somehow the width and height are both I did try to manipulate terminal sizes on the factory, as well as the terminal instance before creating and starting the screen but it had no effect: |
i highly doubt that you want it 10 chars wide and 100 rows high.
anyway, without a stacktrace to the particular spot, nothing else can be
diagnosed.
Ivar Grahn ***@***.***> schrieb am Sa., 5. Okt. 2024, 12:42:
… I think I traced it down. When starting the screen constructed from a
SwingTerminalFrame created by the createSwingTerminal()-method one ends
up here:
image.png (view on web)
<https://github.com/user-attachments/assets/75122347-8416-4e16-b084-73c416befe7b>
Somehow the width and height are both 0 when using the
createSwingTerminal()-method, which seems to be the cause of the
exception.
I did try to manipulate terminal sizes on the factory, as well as the
terminal instance before creating and starting the screen but it had no
effect:
image.png (view on web)
<https://github.com/user-attachments/assets/d4c22720-8e36-425d-b60e-ce76405449ea>
—
Reply to this email directly, view it on GitHub
<#613 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABIDBMST3K52HM55ZQGPZ7TZZ67ALAVCNFSM6AAAAABPIVKPICVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOJVGAYTIMZVGE>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
sorry forget the part about 100 rows... i saw it on phone and misread 10 as
100...
the point about stacktrace still holds...
Andreas Leitgeb ***@***.***> schrieb am Sa., 5. Okt. 2024, 12:59:
… i highly doubt that you want it 10 chars wide and 100 rows high.
anyway, without a stacktrace to the particular spot, nothing else can be
diagnosed.
Ivar Grahn ***@***.***> schrieb am Sa., 5. Okt. 2024, 12:42:
> I think I traced it down. When starting the screen constructed from a
> SwingTerminalFrame created by the createSwingTerminal()-method one ends
> up here:
>
> image.png (view on web)
> <https://github.com/user-attachments/assets/75122347-8416-4e16-b084-73c416befe7b>
>
> Somehow the width and height are both 0 when using the
> createSwingTerminal()-method, which seems to be the cause of the
> exception.
>
> I did try to manipulate terminal sizes on the factory, as well as the
> terminal instance before creating and starting the screen but it had no
> effect:
>
> image.png (view on web)
> <https://github.com/user-attachments/assets/d4c22720-8e36-425d-b60e-ce76405449ea>
>
> —
> Reply to this email directly, view it on GitHub
> <#613 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/ABIDBMST3K52HM55ZQGPZ7TZZ67ALAVCNFSM6AAAAABPIVKPICVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOJVGAYTIMZVGE>
> .
> You are receiving this because you commented.Message ID:
> ***@***.***>
>
|
Extracting the stacktrace from the exception thrown when
When debugging, the first exception seems to exit the execution into the It is the final catch that prints the stacktrace mentioned a few comments prior to this one. |
Do you mind sharing a small sample to reproduce this? So we're all looking/testing at the same code? If the original problem was to set a title and icon for the frame, I thought given SwingTerminalFrame extends from JFrame you could just modify it after it was created. |
Of course! I can recreate the error with minimal code. Also, my apologies for deviating a bit from the original topic! I want to make it clear that I have a fully functional workaround for setting icon and title of the application, thanks to the help of @avl42! By now, the discussion has turned into a debugging session about why Here is the <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>lanterna-swingterminal-error</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.googlecode.lanterna</groupId>
<artifactId>lanterna</artifactId>
<version>3.1.2</version>
</dependency>
</dependencies>
</project>
Here is import com.googlecode.lanterna.bundle.LanternaThemes;
import com.googlecode.lanterna.gui2.AsynchronousTextGUIThread;
import com.googlecode.lanterna.gui2.BasicWindow;
import com.googlecode.lanterna.gui2.MultiWindowTextGUI;
import com.googlecode.lanterna.gui2.SeparateTextGUIThread;
import com.googlecode.lanterna.gui2.Window;
import com.googlecode.lanterna.screen.TerminalScreen;
import com.googlecode.lanterna.terminal.DefaultTerminalFactory;
import com.googlecode.lanterna.terminal.swing.SwingTerminalFrame;
import java.io.IOException;
import java.util.Arrays;
public class Main {
private static final DefaultTerminalFactory terminalFactory = new DefaultTerminalFactory();
private static TerminalScreen screen;
public static void main(String[] args) {
try {
//Workaround. This is what I'm using currently. I'll leave this here for comparison.
//terminalFactory.setForceTextTerminal(false);
//terminalFactory.setForceAWTOverSwing(false);
//final SwingTerminalFrame swingTerminal =
// (SwingTerminalFrame) terminalFactory.createTerminalEmulator();
//Creating the swing terminal via factory => Exception
final SwingTerminalFrame swingTerminal = terminalFactory.createSwingTerminal();
screen = new TerminalScreen(swingTerminal);
screen.startScreen();
//Setting up basic GUI
MultiWindowTextGUI multiWindowTextGUI = new MultiWindowTextGUI(
new SeparateTextGUIThread.Factory(), screen);
((AsynchronousTextGUIThread) multiWindowTextGUI.getGUIThread()).start();
//Creating window
BasicWindow window = new BasicWindow("Simple placeholder window");
window.setHints(Arrays.asList(Window.Hint.CENTERED, Window.Hint.FIT_TERMINAL_WINDOW,
Window.Hint.FULL_SCREEN));
multiWindowTextGUI.setTheme(LanternaThemes.getRegisteredTheme("default"));
multiWindowTextGUI.addWindowAndWait(window);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (screen != null) {
try {
screen.stopScreen();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
} Place these files in the following file-structure (typical maven): ... then place a breakpoint in |
Hello, I'm building a small terminal app using lanterna, I'm pretty much done with my use-case but I noticed this little detail:
Is there any way to customize the Window title and icon? I would like to use my own icon, and I'd rather not it said "SwingTerminalFrame".
The text was updated successfully, but these errors were encountered: