- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用 Intellij-IDEA 的 UI 设计器构建了一个 GUI 应用程序,当我从 IDE 运行它时它运行良好。当我将我的应用程序打包到一个 jar 中并尝试使用 Intelli-IDEA jar runner 运行它时,问题就出现了,它抛出了一个 NPE。
我查看了代码,发现可能是初始化问题,因为我在应用程序中使用的 JPanel 实际上是由 UI Designer 自己初始化的。问题出在初始化 axUI 的 try block 中。
package com.negassagisila.axeereraa;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class Axeereraa {
private final String lookAndFeel;
private final String appHome;
private static final List<Note> notes = new ArrayList<>();
private static File APP_HOME_FILE = null;
private static AxeereraaUI axUI;
private static String theSystem;
private static String theFileSeparator;
private static String theUserHome;
private static String getTheSystem() {
return theSystem;
}
private static String getTheFileSeparator() {
return theFileSeparator;
}
private static String getTheUserHome() {
return theUserHome;
}
String getLookAndFeel() {
return lookAndFeel;
}
private String getAppHome() {
return appHome;
}
public Axeereraa(String appHome, String lookAndFeel) {
this.appHome = appHome;
this.lookAndFeel = lookAndFeel;
}
public static void main(String[] args) {
//TODO: create and instantiate a new concrete Note object for every UI instance
//TODO: perhaps using a builder for the UI instance that will call a factory method for the Note object
theSystem = System.getProperty("os.name");
theFileSeparator = System.getProperty("file.separator");
theUserHome = System.getProperty("user.home");
String theLookAndFeel = UIManager.getSystemLookAndFeelClassName();
String theAppHome = getAxEnvironment(getTheSystem(), getTheFileSeparator(), getTheUserHome());
Axeereraa axRunner = new Axeereraa(theAppHome, theLookAndFeel);
try {
axUI = new AxeereraaUI(axRunner);
} catch (IllegalAccessException |
InstantiationException |
ClassNotFoundException |
UnsupportedLookAndFeelException |
FontFormatException |
NullPointerException|
IOException e) {
e.printStackTrace();
}
APP_HOME_FILE = new File(axRunner.getAppHome());
/**
* checks if the folder exists or not & if it's empty or not,
* and creates it if it doesn't exist.
*/
if (!APP_HOME_FILE.exists() || !APP_HOME_FILE.isDirectory()) {
APP_HOME_FILE.mkdir();
axUI.setNote(new Note("")).showAx();
} else {
displayExistingNotes(axRunner, theFileSeparator);
}
}
/**
* used to save a single Note instance
*/
static void saveNote(Note n) {
try {
final String noteName = "Axeereraa".concat(String.valueOf(n.hashCode())).concat(".ser");
new NoteSaver(new FileOutputStream(APP_HOME_FILE + theFileSeparator + noteName)).save(n);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
/**
* This method is used to load and display the
* pre-existing notes that were already saved.
* @param runner the Axeereraa object needed to set it up.
*/
private static void displayExistingNotes(Axeereraa runner, String theFileSeparator) {
List<Note> result;
try {
result = runner.getExistingNotes(theFileSeparator);
for (Note n : result) {
new AxeereraaUI(runner).setNote(n)
.showAx();
}
if (result.isEmpty()) {
axUI.setNote(new Note("")).showAx();
}
} catch (IllegalAccessException |
InstantiationException |
UnsupportedLookAndFeelException |
ClassNotFoundException |
NullPointerException |
FontFormatException |
IOException e) {
e.printStackTrace();
}
}
/**
* This method is responsible for getting the system environment in which the applications
* runs in.
* @param theSystem name of the OS the application runs in
* @param theFileSeparator the specific file separator of the OS
* @param theUserHome the user folder in which the data will be saved in
* @return a String that's comprised of the user home, the file separator,
* application name & the file separator.
*/
private static String getAxEnvironment(String theSystem, String theFileSeparator, String theUserHome) {
String output;
if (theSystem.startsWith("win")) {
if (theSystem.contains("xp")) {
output = System.getenv("APPDATA") + "\\.Axeereraa\\";
} else {
output = theUserHome + theFileSeparator + ".Axeereraa" + theFileSeparator;
}
} else {
output = theUserHome + theFileSeparator + ".Axeereraa" + theFileSeparator;
}
return output;
}
/**
* This method is responsible for getting the saved Notes from the file system.
* It calls the read() from the NoteReader class.
* @return a List\<Note\> populated with the saved Notes.
* @throws FileNotFoundException if it can't find the folder in which the files are saved in.
*/
private List<Note> getExistingNotes(String theFileSeparator) throws FileNotFoundException {
File savedNotesLocation = new File(APP_HOME_FILE + theFileSeparator);
for (File f: Objects.requireNonNull(savedNotesLocation.listFiles())) {
NoteReader noteReader = new NoteReader(new FileInputStream(f));
synchronized (notes) {
try {
notes.add(noteReader.read());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
return notes;
}
}
AxeereraaUI 类如下所述,当调用 getContentPane().add(axRootPanel)
时它会抛出 NPE;
package com.negassagisila.axeereraa;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
//TODO: 7. run & test (currently no other option, sorry)
/**
* The actual user interface for the Axeereraa application.
*/
public class AxeereraaUI extends JFrame {
private JPanel axRootPanel;
private JScrollPane axRootScrollPane;
private JTextArea axRootTextArea;
private JMenuBar axMenuBar;
private Axeereraa axRunner;
private static int COUNTER;
private JPopupMenu rightClickOptions;
/**
* A constructor that runs every time a new Axeereraa note is needed or built
*/
//TODO: find a way to create a new Note object whenever this constructor runs
//especially if it's run from a saved file location
public AxeereraaUI(Axeereraa axRunner) throws ClassNotFoundException, UnsupportedLookAndFeelException, InstantiationException, IllegalAccessException, IOException, FontFormatException {
this.axRunner = axRunner;
UIManager.setLookAndFeel(axRunner.getLookAndFeel());
AxeereraaUI.this.setFont(
Font.createFont(
Font.TRUETYPE_FONT,
Axeereraa.class.getResourceAsStream(
"/font/Roboto-Medium.ttf"
)
)
);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
getContentPane().add(axRootPanel);
setSize(300, 250);
setTitle("Axeereraa");
buildUI();
setJMenuBar(axMenuBar);
AxeereraaUI.COUNTER++;
}
/**
* This method is responsible for building the components of the UI like
* the menu bar, the menu and it's options.
*/
//TODO: how about adding a Note parameter to this method that builds the UI
//it can get the existing notes as it builds the UI or
//create a new Note object if there aren't any saved notes
private void buildUI() throws IOException {
axMenuBar = new JMenuBar();
rightClickOptions = new JPopupMenu();
axRootScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
axRootScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
axRootTextArea.addMouseListener(new RightClickOptions());
axRootScrollPane.getVerticalScrollBar().setPreferredSize(
new Dimension(3, Integer.MAX_VALUE));
/**
* as the name suggests this sets up the JMenus and their corresponding JMenuItems
*/
SetUpMenuAndMenuItems setUpMenuAndMenuItems = new SetUpMenuAndMenuItems().invoke();
JMenu fileMenu = setUpMenuAndMenuItems.getFileMenu();
JMenu editMenu = setUpMenuAndMenuItems.getEditMenu();
JMenu viewMenu = setUpMenuAndMenuItems.getViewMenu();
JMenu helpMenu = setUpMenuAndMenuItems.getHelpMenu();
/**
* this adds all the above JMenus to the JMenuBar
*/
axMenuBar.add(fileMenu);
axMenuBar.add(editMenu);
axMenuBar.add(viewMenu);
axMenuBar.add(helpMenu);
axRootTextArea.setLineWrap(true);
axRootTextArea.setWrapStyleWord(true);
/**
* As the name suggests this sets up the right click options for the text area.
*/
SetupRightClickOptions setupRightClickOptions = new SetupRightClickOptions().setup();
JMenuItem selectAllRightClickMenuItem = setupRightClickOptions.getSelectAllRightClickMenuItem();
JMenuItem copyRightClickMenuItem = setupRightClickOptions.getCopyRightClickMenuItem();
JMenuItem pasteRightClickMenuItem = setupRightClickOptions.getPasteRightClickMenuItem();
JMenuItem cutRightClickMenuItem = setupRightClickOptions.getCutRightClickMenuItem();
JMenuItem markdownOption = setupRightClickOptions.getMarkdownOption();
JMenu changeNoteColorMenu = setupRightClickOptions.getChangeNoteColorMenu();
/**
* adds all the declared JMenuItems to the right click popup menu.
*/
rightClickOptions.add(selectAllRightClickMenuItem);
rightClickOptions.add(copyRightClickMenuItem);
rightClickOptions.add(pasteRightClickMenuItem);
rightClickOptions.add(cutRightClickMenuItem);
rightClickOptions.add(markdownOption);
rightClickOptions.add(changeNoteColorMenu);
AxeereraaUI.this.setIconImage(
ImageIO.read(
this.getClass().getResource(
"/images/icon.png"
)
)
);
}
/**
* This method is responsible for setting the Note to the UI when the previous Notes are loaded.
* @param note the Note object that will be set to the UI.
* @return the UI object that will be displayed.
*/
AxeereraaUI setNote(Note note) {
setAxRootTextAreaText(note.getWrittenText());
setAxRootTexAreaColor(note.getNoteColor());
return this;
}
/**
* This method is responsible for setting the written text from the saved Note object.
* @param text written text from the saved Note
*/
private void setAxRootTextAreaText(String text) {
axRootTextArea.setText(text);
}
/**
* This method is responsible for setting the background color of the running instance
* of the application from the saved Note object.
* @param color the color from the saved Note
*/
private void setAxRootTexAreaColor(Color color) {
//axRootPanel.setBackground(color);
axRootTextArea.setBackground(color);
}
/**
* This method displays the GUI to the user on the Event Dispatcher Thread (EDT).
*/
void showAx() {
/**
* This calls the EventQueue.invokeLater() method from the EventQueue class so as to run the
* AxeereraaUI on the EDT.
*/
EventQueue.invokeLater(() -> {
try {
buildUI();
setLocationByPlatform(true);
setVisible(true);
} catch (IOException e) {
e.printStackTrace();
}
}
);
}
/**
* This method is used to get a single instance of the Note object from the UI
* @return new Note(written text, NoteColor)
*/
private Note getNote() {
return new Note(this.axRootTextArea.getText(), this.getAxRooTextAreaColor(this.axRootTextArea.getBackground()));
}
/**
* this method gets the note color from the TextArea background and returns it's equivalent
* to the calling method as a NoteColor enum object.
* @param axRootTextAreaBackgroundColor contains the color of the TextArea.
* @return outputNoteColor is the NoteColor enum object.
*/
private NoteColor getAxRooTextAreaColor(Color axRootTextAreaBackgroundColor) {
NoteColor outputNoteColor;
if (axRootTextAreaBackgroundColor.equals(NoteColor.getTheColorOfTheNote(NoteColor.lightGreen))) {
outputNoteColor = NoteColor.lightGreen;
} else if (axRootTextAreaBackgroundColor.equals(NoteColor.getTheColorOfTheNote(NoteColor.lightRed))) {
outputNoteColor = NoteColor.lightRed;
} else {
outputNoteColor = NoteColor.lightYellow;
}
return outputNoteColor;
}
/**
* This method is responsible for setting the application always on top
* @param status boolean value to be passed to the instance of the UI.
*/
private void stayOnTop(boolean status) {
/**
* called on every instance of the UI, method from the JFrame class.
*/
this.setAlwaysOnTop(status);
/**
* changes the icon to lock to show that the result
*/
displayLockIcon(status);
}
/**
* changes the icon to lock to show that the result
* @param status boolean value of that checks if the always on top has been set
*/
private void displayLockIcon(boolean status) {
//todo: find a way to display the lock.png image on the axRootPanel or axRootTextArea
if (status) {
try {
Image lockIcon = ImageIO.read(this.getClass().getResource("/images/lock.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* This method is responsible for removing the deleted note from the UI
*/
private void removeNote() {
this.setVisible(false);
AxeereraaUI.COUNTER--;
//TODO: delete the Note file
if (AxeereraaUI.COUNTER == 0) {
System.exit(0);
}
//NoteDeleter.deleteNote();
}
/**
* This method is responsible for displaying the markdown containing JEditorPane.
* It calls the remove() method from the root scroll pane to remove the currently displayed
* axRootTextArea and instead calls the add() method to insert the jEditorPane.
* @param jEditorPane the editor pane that contains the markdown that will be displayed
*/
private void showMarkdown(JEditorPane jEditorPane) {
jEditorPane.addMouseListener(new RightClickOptions());
this.axRootScrollPane.getViewport().remove(axRootTextArea);
this.axRootScrollPane.getViewport().add(jEditorPane);
}
/**
* This method is responsible for showing the raw text instead of the markdown.
*/
private void showRawText() {
this.axRootScrollPane.getViewport().add(axRootTextArea);
}
/**
* This method creates and displays a JDialog that
* contains the necessary info about the application.
* @param titleOfDialog that will be passed to the JDialog setTitle() method.
*/
private void displayDialog(String titleOfDialog) {
String messageText = null;
if (titleOfDialog.equals("About")) {
messageText = "Axeereraa version 1.0.0\n" +
"For more info \ngo to the github repo:\n" +
"github.com/NegassaB/Axeereraa";
} else if(titleOfDialog.equals("Contact")){
messageText = "You can reach the developer via\n" +
"email or using github.\n" +
"negassab16@gmail.com\n" +
"and github.com/NegassaB";
}
JOptionPane.showMessageDialog(
AxeereraaUI.this,
messageText,
titleOfDialog,
JOptionPane.INFORMATION_MESSAGE
);
}
/**
* This inner class is responsible for setting up the Menus and their items.
* the entire text found in the
* any selected text in the Axeereraa text area.
*/
private class SetUpMenuAndMenuItems {
private JMenu fileMenu;
private JMenu editMenu;
private JMenu viewMenu;
private JMenu helpMenu;
JMenu getFileMenu() {
return fileMenu;
}
JMenu getEditMenu() {
return editMenu;
}
JMenu getViewMenu() {
return viewMenu;
}
JMenu getHelpMenu() {
return helpMenu;
}
SetUpMenuAndMenuItems invoke() {
fileMenu = new JMenu("file");
editMenu = new JMenu("edit");
viewMenu = new JMenu("view");
helpMenu = new JMenu("help");
JMenuItem[] fileMenuItems = new JMenuItem[3];
fileMenuItems[0] = new JMenuItem("New Note");
fileMenuItems[1] = new JMenuItem("Delete Note");
fileMenuItems[2] = new JMenuItem("Save");
fileMenuItems[0].addActionListener(e -> {
try {
new AxeereraaUI(axRunner)
.setNote(new Note(""))
.showAx();
} catch (UnsupportedLookAndFeelException |
IllegalAccessException |
ClassNotFoundException |
InstantiationException |
FontFormatException |
IOException ex) {
ex.printStackTrace();
}
}
);
fileMenuItems[1].addActionListener(e -> removeNote());
fileMenuItems[2].addActionListener(e -> Axeereraa.saveNote(AxeereraaUI.this.getNote()));
for(JMenuItem m : fileMenuItems) {
fileMenu.add(m);
}
JMenuItem[] editMenuItems = new JMenuItem[4];
editMenuItems[0] = new JMenuItem("Select All");
editMenuItems[1] = new JMenuItem("Cut");
editMenuItems[2] = new JMenuItem("Copy");
editMenuItems[3] = new JMenuItem("Paste");
editMenuItems[0].setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK));
editMenuItems[0].addActionListener(e -> axRootTextArea.selectAll());
editMenuItems[1].setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK));
editMenuItems[1].addActionListener(e -> axRootTextArea.cut());
editMenuItems[2].setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK));
editMenuItems[2].addActionListener(e -> axRootTextArea.copy());
editMenuItems[3].setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK));
editMenuItems[3].addActionListener(e -> axRootTextArea.paste());
for (JMenuItem m : editMenuItems) {
editMenu.add(m);
}
JMenu previewMenu = new JMenu("preview");
JMenuItem[] previewMenuItems = new JMenuItem[2];
previewMenuItems[0] = new JMenuItem("show markdown");
previewMenuItems[0].addActionListener(e -> showMarkdown(DisplayMarkdown.displayMarkdown(axRootTextArea.getText())));
previewMenuItems[1] = new JMenuItem("show raw text");
previewMenuItems[1].addActionListener(e -> showRawText());
for (JMenuItem m : previewMenuItems) {
previewMenu.add(m);
}
JMenu stayOnTopMenu = new JMenu("stay on top");
JMenuItem alwaysOnTopItem = new JMenuItem("Always");
JMenuItem neverOnTopItem = new JMenuItem("Never");
alwaysOnTopItem.addActionListener(e -> stayOnTop(true));
neverOnTopItem.addActionListener(e -> stayOnTop(false));
stayOnTopMenu.add(alwaysOnTopItem);
stayOnTopMenu.add(neverOnTopItem);
viewMenu.add(previewMenu);
viewMenu.add(stayOnTopMenu);
JMenuItem[] helpMenuItems = new JMenuItem[2];
helpMenuItems[0] = new JMenuItem("About");
helpMenuItems[0].addActionListener(e -> displayDialog("About"));
helpMenuItems[1] = new JMenuItem("Contact Developer");
helpMenuItems[1].addActionListener(e -> displayDialog("Contact"));
for (JMenuItem m : helpMenuItems) {
helpMenu.add(m);
}
return this;
}
}
/**
* This class displays the right click options when the axRootTextArea is right clicked.
*/
private class RightClickOptions extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
showRightClickOptions(e);
}
private void showRightClickOptions(MouseEvent e) {
if (e.isPopupTrigger()) {
rightClickOptions.show(e.getComponent(), e.getX(), e.getY());
}
}
}
/**
* This inner class is responsible for setting up all the necessary right click options
* by using JPopupMenu. It's method @method setup() will conduct the necessary steps and
* package it in the SetupRightClickOptions instance object.
*/
private class SetupRightClickOptions {
JMenuItem selectAllRightClickMenuItem;
JMenuItem copyRightClickMenuItem;
JMenuItem pasteRightClickMenuItem;
JMenuItem cutRightClickMenuItem;
JMenu markdownOption;
JMenu changeNoteColorMenu;
/**
* This method is responsible for wiring up the necessary functionality of the JPopupMenu with
* it's JMenuItems instantiated above. It will set the keyboard accelerators and the
* ActionListeners for all the MenuItems.
* @return this running instance of SetupRightClickOptions class
*/
SetupRightClickOptions setup() {
selectAllRightClickMenuItem = new JMenuItem("select all");
copyRightClickMenuItem = new JMenuItem("copy");
pasteRightClickMenuItem = new JMenuItem("paste");
cutRightClickMenuItem = new JMenuItem("cut");
markdownOption = new JMenu("preview");
changeNoteColorMenu = new JMenu("change Color");
selectAllRightClickMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK));
selectAllRightClickMenuItem.addActionListener(e -> axRootTextArea.selectAll());
copyRightClickMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK));
copyRightClickMenuItem.addActionListener(e -> axRootTextArea.copy());
pasteRightClickMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK));
pasteRightClickMenuItem.addActionListener(e -> axRootTextArea.paste());
cutRightClickMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK));
cutRightClickMenuItem.addActionListener(e -> axRootTextArea.cut());
JMenuItem[] noteColorMenuItems = new JMenuItem[3];
noteColorMenuItems[0] = new JMenuItem("light green");
noteColorMenuItems[1] = new JMenuItem("light yellow");
noteColorMenuItems[2] = new JMenuItem("light red");
noteColorMenuItems[0].addActionListener(e -> axRootTextArea.setBackground(
NoteColor.getTheColorOfTheNote(NoteColor.lightGreen)
));
noteColorMenuItems[1].addActionListener(e -> axRootTextArea.setBackground(
NoteColor.getTheColorOfTheNote(NoteColor.lightYellow)
));
noteColorMenuItems[2].addActionListener(e -> axRootTextArea.setBackground(
NoteColor.getTheColorOfTheNote(NoteColor.lightRed)
));
for (JMenuItem m : noteColorMenuItems) {
changeNoteColorMenu.add(m);
}
JMenuItem[] markdownOptions = new JMenuItem[2];
markdownOptions[0] = new JMenuItem("show markdown");
markdownOptions[0].addActionListener(e -> showMarkdown(DisplayMarkdown.displayMarkdown(axRootTextArea.getText())));
markdownOptions[1] = new JMenuItem("back to raw text");
markdownOptions[1].addActionListener(e -> showRawText());
for (JMenuItem m : markdownOptions) {
markdownOption.add(m);
}
return this;
}
/**
* Method used to get the selectAllRightClickMenuItem
* @return selectAllRightClickMenuItem
*/
JMenuItem getSelectAllRightClickMenuItem() {
return selectAllRightClickMenuItem;
}
/**
* Method used to get the copyRightClickMenuItem
* @return copyRightClickMenuItem
*/
JMenuItem getCopyRightClickMenuItem() {
return copyRightClickMenuItem;
}
/**
* Method used to get the pasteRightClickMenuItem
* @return pasteRightClickMenuItem
*/
JMenuItem getPasteRightClickMenuItem() {
return pasteRightClickMenuItem;
}
/**
* Method used to get the cutRightClickMenuItem
* @return cutRightClickMenuItem
*/
JMenuItem getCutRightClickMenuItem() {
return cutRightClickMenuItem;
}
/**
* Method used to get the markdownOption
* @return markdownOption
*/
JMenuItem getMarkdownOption() {
return markdownOption;
}
/**
* Method used to get the changeNoteColorMenu
* @return changeNoteColorMenu
*/
JMenu getChangeNoteColorMenu() {
return changeNoteColorMenu;
}
}
}
/usr/local/java/jdk1.8.0_191/bin/java -Dfile.encoding=UTF-8 -jar /home/gadd/IntelliJIDEAProjects/Axeereraa/build/libs/Axeereraa-1.0-SNAPSHOT.jar
java.lang.NullPointerException
at java.awt.Container.addImpl(Container.java:1095)
at java.awt.Container.add(Container.java:419)
at com.negassagisila.axeereraa.AxeereraaUI.<init>(AxeereraaUI.java:50)
at com.negassagisila.axeereraa.Axeereraa.main(Axeereraa.java:60)
Process finished with exit code 1
我希望它像在打包到 jar 之前那样运行,即添加 JPanel 时没有任何问题。我怎样才能做到这一点?或者,我如何初始化 UI 设计器的 Jpanel,即 private JPanel axRootPanel
以便它工作。哦,我正在使用 gradle 脚本而不是 Intellij 自己的 b/c 生成 jar,因为某些原因它对我不起作用。如果有任何帮助,我已将 build.gralde 文件放在下面。
plugins {
id 'java'
}
jar {
manifest {
attributes 'Main-Class': 'com.negassagisila.axeereraa.Axeereraa'
}
from {
configurations.compile.collect {it.isDirectory() ? it : zipTree(it)}
}
}
version '1.0.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
jcenter()
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
// compile files("libs/annotations-16.0.2.jar")
testImplementation 'org.mockito:mockito-core:2.1.0'
testImplementation 'junit:junit:4.12'
testImplementation 'org.hamcrest:hamcrest-all:1.3'
compile 'com.vladsch.flexmark:flexmark-all:0.40.32'
}
apply plugin: 'java'
提前谢谢你。
最佳答案
对于可能遇到此问题的任何其他人,this is the solution .因此,正如该答案中所述,我更改了 AxeereraaUI.java 类,而不是将依赖项设置为 flatDir 并指向 rootDir,而是将该文件复制到我自己的 libs 目录,并在我的构建的依赖项部分中声明它.gradle。AxeereraaUI 类
package com.negassagisila.axeereraa;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
//TODO: 7. run & test (currently no other option, sorry)
/**
* The actual user interface for the Axeereraa application.
*/
public class AxeereraaUI extends JFrame {
private JPanel axRootPanel;
private JScrollPane axRootScrollPane;
private JTextArea axRootTextArea;
private JMenuBar axMenuBar;
private Axeereraa axRunner;
private static int COUNTER;
private JPopupMenu rightClickOptions;
/**
* A constructor that runs every time a new Axeereraa note is needed or built
*/
//TODO: find a way to create a new Note object whenever this constructor runs
//especially if it's run from a saved file location
public AxeereraaUI(Axeereraa axRunner) throws ClassNotFoundException, UnsupportedLookAndFeelException, InstantiationException, IllegalAccessException, IOException, FontFormatException {
this.axRunner = axRunner;
UIManager.setLookAndFeel(axRunner.getLookAndFeel());
AxeereraaUI.this.setFont(
Font.createFont(
Font.TRUETYPE_FONT,
Axeereraa.class.getResourceAsStream(
"/font/Roboto-Medium.ttf"
)
)
);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
getContentPane().add(axRootPanel);
setSize(300, 250);
setTitle("Axeereraa");
buildUI();
setJMenuBar(axMenuBar);
AxeereraaUI.COUNTER++;
}
/**
* This method is responsible for building the components of the UI like
* the menu bar, the menu and it's options.
*/
//TODO: how about adding a Note parameter to this method that builds the UI
//it can get the existing notes as it builds the UI or
//create a new Note object if there aren't any saved notes
private void buildUI() throws IOException {
axMenuBar = new JMenuBar();
rightClickOptions = new JPopupMenu();
axRootScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
axRootScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
axRootTextArea.addMouseListener(new RightClickOptions());
axRootScrollPane.getVerticalScrollBar().setPreferredSize(
new Dimension(3, Integer.MAX_VALUE));
/**
* as the name suggests this sets up the JMenus and their corresponding JMenuItems
*/
SetUpMenuAndMenuItems setUpMenuAndMenuItems = new SetUpMenuAndMenuItems().invoke();
JMenu fileMenu = setUpMenuAndMenuItems.getFileMenu();
JMenu editMenu = setUpMenuAndMenuItems.getEditMenu();
JMenu viewMenu = setUpMenuAndMenuItems.getViewMenu();
JMenu helpMenu = setUpMenuAndMenuItems.getHelpMenu();
/**
* this adds all the above JMenus to the JMenuBar
*/
axMenuBar.add(fileMenu);
axMenuBar.add(editMenu);
axMenuBar.add(viewMenu);
axMenuBar.add(helpMenu);
axRootTextArea.setLineWrap(true);
axRootTextArea.setWrapStyleWord(true);
/**
* As the name suggests this sets up the right click options for the text area.
*/
SetupRightClickOptions setupRightClickOptions = new SetupRightClickOptions().setup();
JMenuItem selectAllRightClickMenuItem = setupRightClickOptions.getSelectAllRightClickMenuItem();
JMenuItem copyRightClickMenuItem = setupRightClickOptions.getCopyRightClickMenuItem();
JMenuItem pasteRightClickMenuItem = setupRightClickOptions.getPasteRightClickMenuItem();
JMenuItem cutRightClickMenuItem = setupRightClickOptions.getCutRightClickMenuItem();
JMenuItem markdownOption = setupRightClickOptions.getMarkdownOption();
JMenu changeNoteColorMenu = setupRightClickOptions.getChangeNoteColorMenu();
/**
* adds all the declared JMenuItems to the right click popup menu.
*/
rightClickOptions.add(selectAllRightClickMenuItem);
rightClickOptions.add(copyRightClickMenuItem);
rightClickOptions.add(pasteRightClickMenuItem);
rightClickOptions.add(cutRightClickMenuItem);
rightClickOptions.add(markdownOption);
rightClickOptions.add(changeNoteColorMenu);
AxeereraaUI.this.setIconImage(
ImageIO.read(
this.getClass().getResource(
"/images/icon.png"
)
)
);
}
/**
* This method is responsible for setting the Note to the UI when the previous Notes are loaded.
*
* @param note the Note object that will be set to the UI.
* @return the UI object that will be displayed.
*/
AxeereraaUI setNote(Note note) {
setAxRootTextAreaText(note.getWrittenText());
setAxRootTexAreaColor(note.getNoteColor());
return this;
}
/**
* This method is responsible for setting the written text from the saved Note object.
*
* @param text written text from the saved Note
*/
private void setAxRootTextAreaText(String text) {
axRootTextArea.setText(text);
}
/**
* This method is responsible for setting the background color of the running instance
* of the application from the saved Note object.
*
* @param color the color from the saved Note
*/
private void setAxRootTexAreaColor(Color color) {
//axRootPanel.setBackground(color);
axRootTextArea.setBackground(color);
}
/**
* This method displays the GUI to the user on the Event Dispatcher Thread (EDT).
*/
void showAx() {
/**
* This calls the EventQueue.invokeLater() method from the EventQueue class so as to run the
* AxeereraaUI on the EDT.
*/
EventQueue.invokeLater(() -> {
try {
buildUI();
setLocationByPlatform(true);
setVisible(true);
} catch (IOException e) {
e.printStackTrace();
}
}
);
}
/**
* This method is used to get a single instance of the Note object from the UI
*
* @return new Note(written text, NoteColor)
*/
private Note getNote() {
return new Note(this.axRootTextArea.getText(), this.getAxRooTextAreaColor(this.axRootTextArea.getBackground()));
}
/**
* this method gets the note color from the TextArea background and returns it's equivalent
* to the calling method as a NoteColor enum object.
*
* @param axRootTextAreaBackgroundColor contains the color of the TextArea.
* @return outputNoteColor is the NoteColor enum object.
*/
private NoteColor getAxRooTextAreaColor(Color axRootTextAreaBackgroundColor) {
NoteColor outputNoteColor;
if (axRootTextAreaBackgroundColor.equals(NoteColor.getTheColorOfTheNote(NoteColor.lightGreen))) {
outputNoteColor = NoteColor.lightGreen;
} else if (axRootTextAreaBackgroundColor.equals(NoteColor.getTheColorOfTheNote(NoteColor.lightRed))) {
outputNoteColor = NoteColor.lightRed;
} else {
outputNoteColor = NoteColor.lightYellow;
}
return outputNoteColor;
}
/**
* This method is responsible for setting the application always on top
*
* @param status boolean value to be passed to the instance of the UI.
*/
private void stayOnTop(boolean status) {
/**
* called on every instance of the UI, method from the JFrame class.
*/
this.setAlwaysOnTop(status);
/**
* changes the icon to lock to show that the result
*/
displayLockIcon(status);
}
/**
* changes the icon to lock to show that the result
*
* @param status boolean value of that checks if the always on top has been set
*/
private void displayLockIcon(boolean status) {
//todo: find a way to display the lock.png image on the axRootPanel or axRootTextArea
if (status) {
try {
Image lockIcon = ImageIO.read(this.getClass().getResource("/images/lock.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* This method is responsible for removing the deleted note from the UI
*/
private void removeNote() {
this.setVisible(false);
AxeereraaUI.COUNTER--;
//TODO: delete the Note file
if (AxeereraaUI.COUNTER == 0) {
System.exit(0);
}
//NoteDeleter.deleteNote();
}
/**
* This method is responsible for displaying the markdown containing JEditorPane.
* It calls the remove() method from the root scroll pane to remove the currently displayed
* axRootTextArea and instead calls the add() method to insert the jEditorPane.
*
* @param jEditorPane the editor pane that contains the markdown that will be displayed
*/
private void showMarkdown(JEditorPane jEditorPane) {
jEditorPane.addMouseListener(new RightClickOptions());
this.axRootScrollPane.getViewport().remove(axRootTextArea);
this.axRootScrollPane.getViewport().add(jEditorPane);
}
/**
* This method is responsible for showing the raw text instead of the markdown.
*/
private void showRawText() {
this.axRootScrollPane.getViewport().add(axRootTextArea);
}
/**
* This method creates and displays a JDialog that
* contains the necessary info about the application.
*
* @param titleOfDialog that will be passed to the JDialog setTitle() method.
*/
private void displayDialog(String titleOfDialog) {
String messageText = null;
if (titleOfDialog.equals("About")) {
messageText = "Axeereraa version 1.0.0\n" +
"For more info \ngo to the github repo:\n" +
"github.com/NegassaB/Axeereraa";
} else if (titleOfDialog.equals("Contact")) {
messageText = "You can reach the developer via\n" +
"email or using github.\n" +
"negassab16@gmail.com\n" +
"and github.com/NegassaB";
}
JOptionPane.showMessageDialog(
AxeereraaUI.this,
messageText,
titleOfDialog,
JOptionPane.INFORMATION_MESSAGE
);
}
{
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
$$$setupUI$$$();
}
/**
* Method generated by IntelliJ IDEA GUI Designer
* >>> IMPORTANT!! <<<
* DO NOT edit this method OR call it in your code!
*
* @noinspection ALL
*/
private void $$$setupUI$$$() {
axRootPanel = new JPanel();
axRootPanel.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
axRootScrollPane = new JScrollPane();
axRootScrollPane.setEnabled(true);
axRootScrollPane.setVisible(true);
axRootPanel.add(axRootScrollPane, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_BOTH, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_WANT_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
axRootTextArea = new JTextArea();
axRootTextArea.setLineWrap(true);
axRootTextArea.setVisible(true);
axRootScrollPane.setViewportView(axRootTextArea);
}
/**
* @noinspection ALL
*/
public JComponent $$$getRootComponent$$$() {
return axRootPanel;
}
/**
* This inner class is responsible for setting up the Menus and their items.
* the entire text found in the
* any selected text in the Axeereraa text area.
*/
private class SetUpMenuAndMenuItems {
private JMenu fileMenu;
private JMenu editMenu;
private JMenu viewMenu;
private JMenu helpMenu;
JMenu getFileMenu() {
return fileMenu;
}
JMenu getEditMenu() {
return editMenu;
}
JMenu getViewMenu() {
return viewMenu;
}
JMenu getHelpMenu() {
return helpMenu;
}
SetUpMenuAndMenuItems invoke() {
fileMenu = new JMenu("file");
editMenu = new JMenu("edit");
viewMenu = new JMenu("view");
helpMenu = new JMenu("help");
JMenuItem[] fileMenuItems = new JMenuItem[3];
fileMenuItems[0] = new JMenuItem("New Note");
fileMenuItems[1] = new JMenuItem("Delete Note");
fileMenuItems[2] = new JMenuItem("Save");
fileMenuItems[0].addActionListener(e -> {
try {
new AxeereraaUI(axRunner)
.setNote(new Note(""))
.showAx();
} catch (UnsupportedLookAndFeelException |
IllegalAccessException |
ClassNotFoundException |
InstantiationException |
FontFormatException |
IOException ex) {
ex.printStackTrace();
}
}
);
fileMenuItems[1].addActionListener(e -> removeNote());
fileMenuItems[2].addActionListener(e -> Axeereraa.saveNote(AxeereraaUI.this.getNote()));
for (JMenuItem m : fileMenuItems) {
fileMenu.add(m);
}
JMenuItem[] editMenuItems = new JMenuItem[4];
editMenuItems[0] = new JMenuItem("Select All");
editMenuItems[1] = new JMenuItem("Cut");
editMenuItems[2] = new JMenuItem("Copy");
editMenuItems[3] = new JMenuItem("Paste");
editMenuItems[0].setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK));
editMenuItems[0].addActionListener(e -> axRootTextArea.selectAll());
editMenuItems[1].setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK));
editMenuItems[1].addActionListener(e -> axRootTextArea.cut());
editMenuItems[2].setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK));
editMenuItems[2].addActionListener(e -> axRootTextArea.copy());
editMenuItems[3].setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK));
editMenuItems[3].addActionListener(e -> axRootTextArea.paste());
for (JMenuItem m : editMenuItems) {
editMenu.add(m);
}
JMenu previewMenu = new JMenu("preview");
JMenuItem[] previewMenuItems = new JMenuItem[2];
previewMenuItems[0] = new JMenuItem("show markdown");
previewMenuItems[0].addActionListener(e -> showMarkdown(DisplayMarkdown.displayMarkdown(axRootTextArea.getText())));
previewMenuItems[1] = new JMenuItem("show raw text");
previewMenuItems[1].addActionListener(e -> showRawText());
for (JMenuItem m : previewMenuItems) {
previewMenu.add(m);
}
JMenu stayOnTopMenu = new JMenu("stay on top");
JMenuItem alwaysOnTopItem = new JMenuItem("Always");
JMenuItem neverOnTopItem = new JMenuItem("Never");
alwaysOnTopItem.addActionListener(e -> stayOnTop(true));
neverOnTopItem.addActionListener(e -> stayOnTop(false));
stayOnTopMenu.add(alwaysOnTopItem);
stayOnTopMenu.add(neverOnTopItem);
viewMenu.add(previewMenu);
viewMenu.add(stayOnTopMenu);
JMenuItem[] helpMenuItems = new JMenuItem[2];
helpMenuItems[0] = new JMenuItem("About");
helpMenuItems[0].addActionListener(e -> displayDialog("About"));
helpMenuItems[1] = new JMenuItem("Contact Developer");
helpMenuItems[1].addActionListener(e -> displayDialog("Contact"));
for (JMenuItem m : helpMenuItems) {
helpMenu.add(m);
}
return this;
}
}
/**
* This class displays the right click options when the axRootTextArea is right clicked.
*/
private class RightClickOptions extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
showRightClickOptions(e);
}
private void showRightClickOptions(MouseEvent e) {
if (e.isPopupTrigger()) {
rightClickOptions.show(e.getComponent(), e.getX(), e.getY());
}
}
}
/**
* This inner class is responsible for setting up all the necessary right click options
* by using JPopupMenu. It's method @method setup() will conduct the necessary steps and
* package it in the SetupRightClickOptions instance object.
*/
private class SetupRightClickOptions {
JMenuItem selectAllRightClickMenuItem;
JMenuItem copyRightClickMenuItem;
JMenuItem pasteRightClickMenuItem;
JMenuItem cutRightClickMenuItem;
JMenu markdownOption;
JMenu changeNoteColorMenu;
/**
* This method is responsible for wiring up the necessary functionality of the JPopupMenu with
* it's JMenuItems instantiated above. It will set the keyboard accelerators and the
* ActionListeners for all the MenuItems.
*
* @return this running instance of SetupRightClickOptions class
*/
SetupRightClickOptions setup() {
selectAllRightClickMenuItem = new JMenuItem("select all");
copyRightClickMenuItem = new JMenuItem("copy");
pasteRightClickMenuItem = new JMenuItem("paste");
cutRightClickMenuItem = new JMenuItem("cut");
markdownOption = new JMenu("preview");
changeNoteColorMenu = new JMenu("change Color");
selectAllRightClickMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK));
selectAllRightClickMenuItem.addActionListener(e -> axRootTextArea.selectAll());
copyRightClickMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK));
copyRightClickMenuItem.addActionListener(e -> axRootTextArea.copy());
pasteRightClickMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK));
pasteRightClickMenuItem.addActionListener(e -> axRootTextArea.paste());
cutRightClickMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK));
cutRightClickMenuItem.addActionListener(e -> axRootTextArea.cut());
JMenuItem[] noteColorMenuItems = new JMenuItem[3];
noteColorMenuItems[0] = new JMenuItem("light green");
noteColorMenuItems[1] = new JMenuItem("light yellow");
noteColorMenuItems[2] = new JMenuItem("light red");
noteColorMenuItems[0].addActionListener(e -> axRootTextArea.setBackground(
NoteColor.getTheColorOfTheNote(NoteColor.lightGreen)
));
noteColorMenuItems[1].addActionListener(e -> axRootTextArea.setBackground(
NoteColor.getTheColorOfTheNote(NoteColor.lightYellow)
));
noteColorMenuItems[2].addActionListener(e -> axRootTextArea.setBackground(
NoteColor.getTheColorOfTheNote(NoteColor.lightRed)
));
for (JMenuItem m : noteColorMenuItems) {
changeNoteColorMenu.add(m);
}
JMenuItem[] markdownOptions = new JMenuItem[2];
markdownOptions[0] = new JMenuItem("show markdown");
markdownOptions[0].addActionListener(e -> showMarkdown(DisplayMarkdown.displayMarkdown(axRootTextArea.getText())));
markdownOptions[1] = new JMenuItem("back to raw text");
markdownOptions[1].addActionListener(e -> showRawText());
for (JMenuItem m : markdownOptions) {
markdownOption.add(m);
}
return this;
}
/**
* Method used to get the selectAllRightClickMenuItem
* @return selectAllRightClickMenuItem
*/
JMenuItem getSelectAllRightClickMenuItem() {
return selectAllRightClickMenuItem;
}
/**
* Method used to get the copyRightClickMenuItem
* @return copyRightClickMenuItem
*/
JMenuItem getCopyRightClickMenuItem() {
return copyRightClickMenuItem;
}
/**
* Method used to get the pasteRightClickMenuItem
* @return pasteRightClickMenuItem
*/
JMenuItem getPasteRightClickMenuItem() {
return pasteRightClickMenuItem;
}
/**
* Method used to get the cutRightClickMenuItem
* @return cutRightClickMenuItem
*/
JMenuItem getCutRightClickMenuItem() {
return cutRightClickMenuItem;
}
/**
* Method used to get the markdownOption
* @return markdownOption
*/
JMenuItem getMarkdownOption() {
return markdownOption;
}
/**
* Method used to get the changeNoteColorMenu
* @return changeNoteColorMenu
*/
JMenu getChangeNoteColorMenu() {
return changeNoteColorMenu;
}
}
}
和 build.gradle 文件
plugins {
id 'java'
}
jar {
manifest {
attributes 'Main-Class': 'com.negassagisila.axeereraa.Axeereraa'
}
from {
configurations.compile.collect {it.isDirectory() ? it : zipTree(it)}
}
}
version '1.0.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
jcenter()
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
compile files("libs/forms_rt.jar")
testImplementation 'org.mockito:mockito-core:2.1.0'
testImplementation 'junit:junit:4.12'
testImplementation 'org.hamcrest:hamcrest-all:1.3'
compile 'com.vladsch.flexmark:flexmark-all:0.40.32'
}
apply plugin: 'java'
关于java - 从 jar 运行我的应用程序时,从我的 UI 设计器生成的 JPanel 中抛出 NPE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55969671/
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!